System.Windows.Forms.Timer 基於窗體應用程式 阻塞同步 單線程 timer中處理時間較長則導致定時誤差極大。 System.Timers.Timer 基於服務 非阻塞非同步 多線程 當啟動_wTimer.Start(),輸出結果。在_wTimer_Tick 休眠2秒阻塞主線程 ...
System.Windows.Forms.Timer
基於窗體應用程式
阻塞同步
單線程
timer中處理時間較長則導致定時誤差極大。
System.Timers.Timer
基於服務
非阻塞非同步
多線程
/// <summary> /// windows定時器 /// </summary> System.Windows.Forms.Timer _wTimer; /// <summary> /// 應用程式生成定時器 /// </summary> System.Timers.Timer _tTimer; private void Form1_Load(object sender, EventArgs e) { _wTimer = new System.Windows.Forms.Timer(); _wTimer.Interval = 500;//設置時間間隔500毫秒 _wTimer.Tick += _wTimer_Tick; _wTimer.Start();//啟動定時器 _tTimer = new System.Timers.Timer(); _tTimer.Interval = 500;//設置時間間隔500毫秒 _tTimer.Elapsed += _tTimer_Elapsed; //_tTimer.Start(); } void _tTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { Print("_tTimer_Elapsed" + _count.ToString()); Thread.Sleep(2000);//休眠2秒 _count++; } void _wTimer_Tick(object sender, EventArgs e) { Print("_wTimer_Tick" + _count.ToString()); Thread.Sleep(2000);//休眠2秒 _count++; } private void Print(string msg) { if (this.InvokeRequired) { this.BeginInvoke((Action)delegate() { textBox1.AppendText(msg + "\r\n"); }); } else { textBox1.AppendText(msg + "\r\n"); } }
當啟動_wTimer.Start(),輸出結果。在_wTimer_Tick 休眠2秒阻塞主線程,導致程式假死2秒。而且事件沒在沒有處理完成不會進行下次,所以_count 結果每次只輸出一次、。
當啟動_tTimer.Start(),每隔500毫秒添加一個線程。由於非同步只要到達時間間隔則自動生成下個線程,不管上個線程是否處理完成。
所以_count的結果會有多次輸出。
如果想解決 system.timers 沒到時間間隔只生成一個線程或者說上次沒有處理完下次則等待處理可以在處理前添加_tTimer.stop(),完成後再次啟動_tTimer.start()。