某些場景併發量太高,需要採用隊列輔助,特此備註:多線程隊列,先進先出 某些情況也會用到阻塞當前線程,等待伺服器返回或者耗時的處理,這種情況,可採用信號量輔助 1 ManualResetEvent allDone = new ManualResetEvent(false);//初始化,開啟阻塞 2 a ...
某些場景併發量太高,需要採用隊列輔助,特此備註:多線程隊列,先進先出
某些情況也會用到阻塞當前線程,等待伺服器返回或者耗時的處理,這種情況,可採用信號量輔助
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 }