說(shuō)明:c#多線(xiàn)程排隊(duì)隊(duì)列實(shí)現(xiàn)的源碼,,極好的展現(xiàn)了多線(xiàn)程的控制。喜歡的給點(diǎn)留言我加點(diǎn)分,,然后多下載東東 多學(xué)習(xí) 多給大家免費(fèi)傳,!謝謝你們 using System; using System.Threading; using System.Collections; using System.Collections.Generic; // 將線(xiàn)程同步事件封裝在此類(lèi)中, // 以便于將這些事件傳遞給 Consumer 和 // Producer 類(lèi),。 public class SyncEvents { public SyncEvents() { // AutoResetEvent 用于“新項(xiàng)”事件,,因?yàn)?/font> // 我們希望每當(dāng)使用者線(xiàn)程響應(yīng)此事件時(shí), // 此事件就會(huì)自動(dòng)重置,。 _newItemEvent = new AutoResetEvent(false); // ManualResetEvent 用于“退出”事件,,因?yàn)?/font> // 我們希望發(fā)出此事件的信號(hào)時(shí)有多個(gè)線(xiàn)程響應(yīng)。 // 如果使用 AutoResetEvent,,事件 // 對(duì)象將在單個(gè)線(xiàn)程作出響應(yīng)之后恢復(fù)為 // 未發(fā)信號(hào)的狀態(tài),,而其他線(xiàn)程將 // 無(wú)法終止。 _exitThreadEvent = new ManualResetEvent(false); // 這兩個(gè)事件也放在一個(gè) WaitHandle 數(shù)組中,,以便 // 使用者線(xiàn)程可以使用 WaitAny 方法 // 阻塞這兩個(gè)事件,。 _eventArray = new WaitHandle[2]; _eventArray[0] = _newItemEvent; _eventArray[1] = _exitThreadEvent; } // 公共屬性允許對(duì)事件進(jìn)行安全訪(fǎng)問(wèn)。 public EventWaitHandle ExitThreadEvent { get { return _exitThreadEvent; } } public EventWaitHandle NewItemEvent { get { return _newItemEvent; } } public WaitHandle[] EventArray { get { return _eventArray; } } private EventWaitHandle _newItemEvent; private EventWaitHandle _exitThreadEvent; private WaitHandle[] _eventArray; } // Producer 類(lèi)(使用一個(gè)輔助線(xiàn)程) // 將項(xiàng)異步添加到隊(duì)列中,共添加 20 個(gè)項(xiàng),。 public class Producer { public Producer(Queue<int> q, SyncEvents e) { _queue = q; _syncEvents = e; } public void ThreadRun() { int count = 0; Random r = new Random(); while (!_syncEvents.ExitThreadEvent.WaitOne(0, false)) { lock (((ICollection)_queue).SyncRoot) { while (_queue.Count < 20) { _queue.Enqueue(r.Next(0, 100)); _syncEvents.NewItemEvent.Set(); count++; } } } Console.WriteLine("Producer thread: produced {0} items", count); } private Queue<int> _queue; private SyncEvents _syncEvents; } // Consumer 類(lèi)通過(guò)自己的輔助線(xiàn)程使用隊(duì)列 // 中的項(xiàng),。Producer 類(lèi)使用 NewItemEvent // 將新項(xiàng)通知 Consumer 類(lèi)。 public class Consumer { public Consumer(Queue<int> q, SyncEvents e) { _queue = q; _syncEvents = e; } public void ThreadRun() { int count = 0; while (WaitHandle.WaitAny(_syncEvents.EventArray) != 1) { lock (((ICollection)_queue).SyncRoot) { int item = _queue.Dequeue(); } count++; } Console.WriteLine("Consumer Thread: consumed {0} items", count); } private Queue<int> _queue; private SyncEvents _syncEvents; } public class ThreadSyncSample { private static void ShowQueueContents(Queue<int> q) { // 對(duì)集合進(jìn)行枚舉本來(lái)就不是線(xiàn)程安全的,, // 因此在整個(gè)枚舉過(guò)程中鎖定集合以防止 // 使用者和制造者線(xiàn)程修改內(nèi)容 // 是絕對(duì)必要的,。(此方法僅由 // 主線(xiàn)程調(diào)用。) lock (((ICollection)q).SyncRoot) { foreach (int i in q) { Console.Write("{0} ", i); } } Console.WriteLine(); } static void Main() { // 配置結(jié)構(gòu),,該結(jié)構(gòu)包含線(xiàn)程同步 // 所需的事件信息,。 SyncEvents syncEvents = new SyncEvents(); // 泛型隊(duì)列集合用于存儲(chǔ)要制造和使用的 // 項(xiàng)。此例中使用的是“int”,。 Queue<int> queue = new Queue<int>(); // 創(chuàng)建對(duì)象,,一個(gè)用于制造項(xiàng),一個(gè)用于 // 使用項(xiàng),。將隊(duì)列和線(xiàn)程同步事件傳遞給 // 這兩個(gè)對(duì)象,。 Console.WriteLine("Configuring worker threads..."); Producer producer = new Producer(queue, syncEvents); Consumer consumer = new Consumer(queue, syncEvents); // 為制造者對(duì)象和使用者對(duì)象創(chuàng)建線(xiàn)程 // 對(duì)象。此步驟并不創(chuàng)建或啟動(dòng) // 實(shí)際線(xiàn)程,。 Thread producerThread = new Thread(producer.ThreadRun); Thread consumerThread = new Thread(consumer.ThreadRun); // 創(chuàng)建和啟動(dòng)兩個(gè)線(xiàn)程,。 Console.WriteLine("Launching producer and consumer threads..."); producerThread.Start(); consumerThread.Start(); // 為制造者線(xiàn)程和使用者線(xiàn)程設(shè)置 10 秒的運(yùn)行時(shí)間。 // 使用主線(xiàn)程(執(zhí)行此方法的線(xiàn)程) // 每隔 2.5 秒顯示一次隊(duì)列內(nèi)容,。 for (int i = 0; i < 4; i++) { Thread.Sleep(2500); ShowQueueContents(queue); } // 向使用者線(xiàn)程和制造者線(xiàn)程發(fā)出終止信號(hào)。 // 這兩個(gè)線(xiàn)程都會(huì)響應(yīng),,由于 ExitThreadEvent 是 // 手動(dòng)重置的事件,因此除非顯式重置,,否則將保持“設(shè)置”。 Console.WriteLine("Signaling threads to terminate..."); syncEvents.ExitThreadEvent.Set(); // 使用 Join 阻塞主線(xiàn)程,,首先阻塞到制造者線(xiàn)程 // 終止,,然后阻塞到使用者線(xiàn)程終止。 Console.WriteLine("main thread waiting for threads to finish..."); producerThread.Join(); consumerThread.Join(); } } |
|
來(lái)自: orion360doc > 《.Net/C#》