c# 多線程排隊隊列實現的源碼


                                                                                   原文:http://blog.csdn.net/loveandangle/article/details/6733642

  1. using System;  

  2. using System.Threading;  
  3.   
  4. using System.Collections;  
  5.   
  6. using System.Collections.Generic;  
  7.   
  8.   
  9. // 將線程同步事件封裝在此類中,    
  10.   
  11. // 以便於將這些事件傳遞給 Consumer 和   
  12.   
  13. // Producer 類。   
  14.   
  15. public class SyncEvents  
  16.   
  17. {  
  18.   
  19.     public SyncEvents()  
  20.   
  21.     {  
  22.   
  23.         // AutoResetEvent 用於“新項”事件,因為   
  24.   
  25.         // 我們希望每當使用者線程響應此事件時,   
  26.   
  27.         // 此事件就會自動重置。   
  28.   
  29.         _newItemEvent = new AutoResetEvent(false);  
  30.   
  31.   
  32.         // ManualResetEvent 用於“退出”事件,因為   
  33.   
  34.         // 我們希望發出此事件的信號時有多個線程響應。   
  35.   
  36.         // 如果使用 AutoResetEvent,事件   
  37.   
  38.         // 對象將在單個線程作出響應之后恢復為    
  39.   
  40.         // 未發信號的狀態,而其他線程將   
  41.   
  42.         // 無法終止。   
  43.   
  44.         _exitThreadEvent = new ManualResetEvent(false);  
  45.   
  46.   
  47.         // 這兩個事件也放在一個 WaitHandle 數組中,以便   
  48.   
  49.         // 使用者線程可以使用 WaitAny 方法   
  50.   
  51.         // 阻塞這兩個事件。   
  52.   
  53.         _eventArray = new WaitHandle[2];  
  54.   
  55.         _eventArray[0] = _newItemEvent;  
  56.   
  57.         _eventArray[1] = _exitThreadEvent;  
  58.   
  59.     }  
  60.   
  61.   
  62.     // 公共屬性允許對事件進行安全訪問。   
  63.   
  64.     public EventWaitHandle ExitThreadEvent  
  65.   
  66.     {  
  67.   
  68.         get { return _exitThreadEvent; }  
  69.   
  70.     }  
  71.   
  72.     public EventWaitHandle NewItemEvent  
  73.   
  74.     {  
  75.   
  76.         get { return _newItemEvent; }  
  77.   
  78.     }  
  79.   
  80.     public WaitHandle[] EventArray  
  81.   
  82.     {  
  83.   
  84.         get { return _eventArray; }  
  85.   
  86.     }  
  87.   
  88.   
  89.     private EventWaitHandle _newItemEvent;  
  90.   
  91.     private EventWaitHandle _exitThreadEvent;  
  92.   
  93.     private WaitHandle[] _eventArray;  
  94.   
  95. }  
  96.   
  97.   
  98. // Producer 類(使用一個輔助線程)   
  99.   
  100. // 將項異步添加到隊列中,共添加 20 個項。   
  101.   
  102. public class Producer   
  103.   
  104. {  
  105.   
  106.     public Producer(Queue<int> q, SyncEvents e)  
  107.   
  108.     {  
  109.   
  110.         _queue = q;  
  111.   
  112.         _syncEvents = e;  
  113.   
  114.     }  
  115.   
  116.     public void ThreadRun()  
  117.   
  118.     {  
  119.   
  120.         int count = 0;  
  121.   
  122.         Random r = new Random();  
  123.   
  124.         while (!_syncEvents.ExitThreadEvent.WaitOne(0, false))  
  125.   
  126.         {  
  127.   
  128.             lock (((ICollection)_queue).SyncRoot)  
  129.   
  130.             {  
  131.   
  132.                 while (_queue.Count < 20)  
  133.   
  134.                 {  
  135.   
  136.                     _queue.Enqueue(r.Next(0, 100));  
  137.   
  138.                     _syncEvents.NewItemEvent.Set();  
  139.   
  140.                     count++;  
  141.   
  142.                 }  
  143.   
  144.             }  
  145.   
  146.         }  
  147.   
  148.         Console.WriteLine("Producer thread: produced {0} items", count);  
  149.   
  150.     }  
  151.   
  152.     private Queue<int> _queue;  
  153.   
  154.     private SyncEvents _syncEvents;  
  155.   
  156. }  
  157.   
  158.   
  159. // Consumer 類通過自己的輔助線程使用隊列   
  160.   
  161. // 中的項。Producer 類使用 NewItemEvent    
  162.   
  163. // 將新項通知 Consumer 類。   
  164.   
  165. public class Consumer  
  166.   
  167. {  
  168.   
  169.     public Consumer(Queue<int> q, SyncEvents e)  
  170.   
  171.     {  
  172.   
  173.         _queue = q;  
  174.   
  175.         _syncEvents = e;  
  176.   
  177.     }  
  178.   
  179.     public void ThreadRun()  
  180.   
  181.     {  
  182.   
  183.         int count = 0;  
  184.   
  185.         while (WaitHandle.WaitAny(_syncEvents.EventArray) != 1)  
  186.   
  187.         {  
  188.   
  189.             lock (((ICollection)_queue).SyncRoot)  
  190.   
  191.             {  
  192.   
  193.                 int item = _queue.Dequeue();  
  194.   
  195.             }  
  196.   
  197.             count++;  
  198.   
  199.         }  
  200.   
  201.         Console.WriteLine("Consumer Thread: consumed {0} items", count);  
  202.   
  203.     }  
  204.   
  205.     private Queue<int> _queue;  
  206.   
  207.     private SyncEvents _syncEvents;  
  208.   
  209. }  
  210.   
  211.   
  212. public class ThreadSyncSample  
  213.   
  214. {  
  215.   
  216.     private static void ShowQueueContents(Queue<int> q)  
  217.   
  218.     {  
  219.   
  220.         // 對集合進行枚舉本來就不是線程安全的,   
  221.   
  222.         // 因此在整個枚舉過程中鎖定集合以防止   
  223.   
  224.         // 使用者和制造者線程修改內容   
  225.   
  226.         // 是絕對必要的。(此方法僅由   
  227.   
  228.         // 主線程調用。)   
  229.   
  230.         lock (((ICollection)q).SyncRoot)  
  231.   
  232.         {  
  233.   
  234.             foreach (int i in q)  
  235.   
  236.             {  
  237.   
  238.                 Console.Write("{0} ", i);  
  239.   
  240.             }  
  241.   
  242.         }  
  243.   
  244.         Console.WriteLine();  
  245.   
  246.     }  
  247.   
  248.   
  249.     static void Main()  
  250.   
  251.     {  
  252.   
  253.         // 配置結構,該結構包含線程同步   
  254.   
  255.         // 所需的事件信息。   
  256.   
  257.         SyncEvents syncEvents = new SyncEvents();  
  258.   
  259.   
  260.         // 泛型隊列集合用於存儲要制造和使用的   
  261.   
  262.         // 項。此例中使用的是“int”。   
  263.   
  264.         Queue<int> queue = new Queue<int>();  
  265.   
  266.   
  267.         // 創建對象,一個用於制造項,一個用於   
  268.   
  269.         // 使用項。將隊列和線程同步事件傳遞給   
  270.   
  271.         // 這兩個對象。   
  272.   
  273.         Console.WriteLine("Configuring worker threads...");  
  274.   
  275.         Producer producer = new Producer(queue, syncEvents);  
  276.   
  277.         Consumer consumer = new Consumer(queue, syncEvents);  
  278.   
  279.   
  280.         // 為制造者對象和使用者對象創建線程   
  281.   
  282.         // 對象。此步驟並不創建或啟動   
  283.   
  284.         // 實際線程。   
  285.   
  286.         Thread producerThread = new Thread(producer.ThreadRun);  
  287.   
  288.         Thread consumerThread = new Thread(consumer.ThreadRun);  
  289.   
  290.   
  291.         // 創建和啟動兩個線程。   
  292.   
  293.         Console.WriteLine("Launching producer and consumer threads...");          
  294.   
  295.         producerThread.Start();  
  296.   
  297.         consumerThread.Start();  
  298.   
  299.   
  300.         // 為制造者線程和使用者線程設置 10 秒的運行時間。   
  301.   
  302.         // 使用主線程(執行此方法的線程)   
  303.   
  304.         // 每隔 2.5 秒顯示一次隊列內容。   
  305.   
  306.         for (int i = 0; i < 4; i++)  
  307.   
  308.         {  
  309.   
  310.             Thread.Sleep(2500);  
  311.   
  312.             ShowQueueContents(queue);  
  313.   
  314.         }  
  315.   
  316.   
  317.         // 向使用者線程和制造者線程發出終止信號。   
  318.   
  319.         // 這兩個線程都會響應,由於 ExitThreadEvent 是   
  320.   
  321.         // 手動重置的事件,因此除非顯式重置,否則將保持“設置”。   
  322.   
  323.         Console.WriteLine("Signaling threads to terminate...");  
  324.   
  325.         syncEvents.ExitThreadEvent.Set();  
  326.   
  327.   
  328.         // 使用 Join 阻塞主線程,首先阻塞到制造者線程   
  329.   
  330.         // 終止,然后阻塞到使用者線程終止。   
  331.   
  332.         Console.WriteLine("main thread waiting for threads to finish...");  
  333.   
  334.         producerThread.Join();  
  335.   
  336.         consumerThread.Join();  
  337.   
  338.     }  
  339.   
  340. }  

  1. namespace WindowsFormsApplication1  
  2. {  
  3.     public partial class Form3 : Form  
  4.     {  
  5.         public Form3()  
  6.         {  
  7.             InitializeComponent();  
  8.         }  
  9.         public delegate void Delegate1();  
  10.         public delegate void Delegate2(DataTable dt);  
  11.         public void buttonFind_Click(object sender, EventArgs e)  
  12.         {  
  13.             Delegate1 d1 = new Delegate1(Find);  
  14.             d1.BeginInvoke(new AsyncCallback(AsyncCallback1), d1);  
  15.         }  
  16.         public void AsyncCallback1(IAsyncResult iAsyncResult)  
  17.         {  
  18.             Delegate1 d1 = (Delegate1)iAsyncResult.AsyncState;  
  19.             d1.EndInvoke(iAsyncResult);  
  20.         }  
  21.         public void Find()  
  22.         {  
  23.             DataTable dt = new DataTable();  
  24.             dt.Columns.Add("name", typeof(string));  
  25.             dt.Columns.Add("age", typeof(int));  
  26.             AddRow(dt, "張三", 19);  
  27.             AddRow(dt, "張三", 19);  
  28.             AddRow(dt, "李四", 18);  
  29.             this.Invoke(new Delegate2(Bind2), new object[] { dt });  
  30.         }  
  31.         public void AddRow(DataTable dt, string nameint age)  
  32.         {  
  33.             DataRow dr = dt.NewRow();  
  34.             dr["name"] = name;  
  35.             dr["age"] = age;  
  36.             dt.Rows.Add(dr);  
  37.         }  
  38.         public void Bind2(DataTable dt)  
  39.         {  
  40.             this.dataGridView1.DataSource = dt;  
  41.         }  
  42.     }  
  43. }  




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM