多線程,隊列,先進先出、信號量...

某些場景併發量太高,需要採用隊列輔助,特此備註:多線程隊列,先進先出

某些情況也會用到阻塞當前線程,等待服務器返回或者耗時的處理,這種情況,可採用信號量輔助

1 ManualResetEvent allDone = new ManualResetEvent(false);//初始化,開啓阻塞
2 allDone.Reset();//信號量重置,狀態爲阻塞
3 allDone.WaitOne(5*1000);//阻塞當前線程,最大等待5秒
4 allDone.Set();//釋放信號量,將阻塞的線程繼續向下

口水話註解:調用了Set方法將事件設爲true後,不會去調用Reset方法,這將導致事件一直處於true,其它等待的多個線程都會得到執行,直到你手動調用Reset方法。
相當於你把門打開後,需要手動去關(非自動門)。

 

1 AutoResetEvent ReciveResetEvent = new System.Threading.AutoResetEvent(true);//初始化,未開啓阻塞
2 ReciveResetEvent.WaitOne(30000);//阻塞
3 ReciveResetEvent.Set();//釋放後,自動開啓阻塞
口水話註解:調用了Set方法將事件設爲true之後,其中一個等待線程得到執行後,它會自動調用Reset方法,將事件信號設爲false,以阻塞其它的線程。
相當於放一個線程進來,門自動就關了(自動門)。

 

  1 /*
  2     例子:
  3         
  4     //初始化後臺處理消息線程
  5     AsyncQueueDataProcessor<string> asyncQueueDetector = new AsyncQueueDataProcessor<string>();
  6     asyncQueueDetector.ProcessData += AsyncQueue_ProcessData;//事件裏處理有數據時
  7     asyncQueueDetector.Start();
  8 
  9     服務啓動後,使用 asyncQueueDetector.AppendData 追加數據到隊列
 10     */
 11 
 12 
 13     /// <summary>
 14     /// 異步處理隊列數據
 15     /// </summary>
 16     /// <typeparam name="T"></typeparam>
 17     public class AsyncQueueDataProcessor<T> : IDisposable
 18     {
 19         #region 成員變量
 20 
 21         /// <summary>
 22         /// 待處理的數據隊列
 23         /// </summary>
 24         ConcurrentQueue<T> DataQueue;
 25 
 26         /// <summary>
 27         /// 數據處理定時器
 28         /// </summary>
 29         Timer processTimer;
 30 
 31         #endregion
 32 
 33         #region 構造函數
 34 
 35         /// <summary>
 36         /// 初始化
 37         /// </summary>
 38         /// <param name="intervalMillSecond"></param>
 39         public AsyncQueueDataProcessor(int intervalMillSecond = 120)
 40         {
 41             DataQueue = new ConcurrentQueue<T>();
 42             processTimer = new Timer(intervalMillSecond);
 43             processTimer.Elapsed += ProcessTimer_Elapsed;
 44             processTimer.AutoReset = false;
 45         }
 46 
 47         #endregion
 48 
 49         #region 自定義事件
 50 
 51         /// <summary>
 52         /// 數據拋出時觸發
 53         /// </summary>
 54         public event EventHandler<T> ProcessData;
 55 
 56         #endregion
 57 
 58         #region 公共方法
 59 
 60         /// <summary>
 61         /// 釋放所有資源
 62         /// </summary>
 63         public void Dispose()
 64         {
 65             processTimer.Dispose();
 66             ClearData();
 67         }
 68 
 69         /// <summary>
 70         /// 開始處理數據
 71         /// </summary>
 72         public void Start()
 73         {
 74             processTimer.Start();
 75         }
 76 
 77         /// <summary>
 78         /// 停止處理數據
 79         /// </summary>
 80         public void Stop()
 81         {
 82             processTimer.Stop();
 83         }
 84 
 85         /// <summary>
 86         /// 追加數據到隊列
 87         /// </summary>
 88         /// <param name="data"></param>
 89         public void AppendData(T data)
 90         {
 91             DataQueue.Enqueue(data);
 92         }
 93 
 94         /// <summary>
 95         /// 清空隊列數據
 96         /// </summary>
 97         public void ClearData()
 98         {
 99             do
100             {
101             } while (DataQueue.TryDequeue(out T t));
102         }
103         #endregion
104 
105         #region 事件
106 
107         //處理數據時執行
108         private void ProcessTimer_Elapsed(object sender, ElapsedEventArgs e)
109         {
110             T t;
111             if (DataQueue.TryDequeue(out t))
112             {
113                 if (ProcessData != null)
114                 {
115                     try
116                     {
117                         ProcessData(this, t);
118                     }
119                     catch (Exception exp)
120                     {
121                         Debug.WriteLine($"隊列裏面發生了未處理的異常-{exp.Message}\r\n{exp.StackTrace}");
122                     }
123                 }
124             }
125 
126             processTimer.Start();
127         }
128 
129         #endregion
130     }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章