C#四種計時器Timer的區別和用法
1、System.Threading.Timer 線程計時器
1、最底層、輕量級的計時器。基於線程池實現的,工作在輔助線程。
2、它並不是內在線程安全的,並且使用起來比其他計時器更麻煩。此計時器通常不適合 Windows 窗體環境。
構造函數:public Timer(TimerCallback callback, object state, int dueTime, int period);
string state=”.”; //state參數可以傳入想在callback委托中處理的對象。可以傳遞一個AutoRestEvent,在回調函數中向主函數發送信號。 Timer timer=new Timer(TimeMethod,state,100,1000)//100表示多久後開始,1000表示隔多久執行一次。 void TimerMethod(object state) {Console.Write(state.ToString());} timer.Dispose();//取消timer執行
2、System.Timers.Timer 服務器計時器
1、針對服務器的服務程序,基於System.Threading.Timer,被設計並優化成能用於多線程環境。在這種情況下,應該確保事件處理程序不與 UI 交互。在asp.net中一般使用System.Timers.Timer。
2、繼承自Compnent,公開瞭可以SynchronizingObject 屬性,避免瞭線程池中無法訪問主線程中組件的問題(模擬System.Windows.Forms.Timer單線程模式)。但是除非需要對事件的時間安排進行更精確的控制,否則還是應該改為使用 System.Windows.Forms.Timer。
3、AutoReset屬性設置計時器是否在引發Elapsed事件後重新計時,默認為true。如果該屬性設為False,則隻執行timer_Elapsed方法一次。
4、System.Timers.Timer是多線程定時器,如果一個Timer沒有處理完成,到達下一個時間點,新的Timer同樣會被啟動。所以,Timer比較適合執行不太耗時的小任務,若在Timer中運行耗時任務,很容易出現由於超時導致的多線程重入問題,即多個線程同時進入timer_Elapsed方法。
System.Timers.Timer timer = new System.Timers.Timer(); timer.Interval = 500; timer.SynchronizingObject = this; timer.Elapsed+=new System.Timers.ElapsedEventHandler(timer_Elapsed); timer.Start(); private void timer_Elapsed(Object source, Timers.ElapsedEventArgs e) { this.tbTimer.Text = value; }
5、為瞭應對多線程重入問題。可以加鎖,也可以增加標志位。 Interlocked.Exchange提供瞭一種輕量級的線程安全的給對象賦值的方法,所以使用Interlocked.Exchange給變量賦值。
int inTimer = 0; void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (Interlocked.Exchange(ref inTimer, 1) == 0) { Thread.Sleep(3000); string currentThreadId = Thread.CurrentThread.ManagedThreadId.ToString(); this.Dispatcher.BeginInvoke(new Action(() => { this.Label_Result.Content += currentThreadId + ","; }), null); Interlocked.Exchange(ref inTimer, 0); } }
3、System.Windows.Forms.Timer Windows計時器
此計時器直接繼承自Component,它經過瞭專門的優化以便與 Windows 窗體一起使用,並且必須在窗口中使用。
- Windows計時器建立在基於消息的UI線程上運行,精度限定為5ms。Tick事件中執行的事件與主窗體是同一個線程(單線程),並且對與 UI 交互是安全的。
- 隻有Enable和Internal兩個屬性和一個Tick事件,可以使用Start()和Stop()方法控制Enable屬性。
using System.Windows.Forms; public Form1() { InitializeComponent(); this.Load += delegate { Timer timer = new Timer(); timer.Interval = 500; timer.Tick += delegate { System.Diagnostics.Debug.WriteLine($"Timer Thread: {System.Threading.Thread.CurrentThread.ManagedThreadId}"); System.Diagnostics.Debug.WriteLine($"Is Thread Pool: {System.Threading.Thread.CurrentThread.IsThreadPoolThread}"); this.lblTimer.Text = DateTime.Now.ToLongTimeString(); }; timer.Start(); System.Diagnostics.Debug.WriteLine($"Main Thread: {System.Threading.Thread.CurrentThread.ManagedThreadId}"); }; }
4. System.Windows.Threading.DispatcherTimer
主要用於WPF中。屬性和方法與System.Windows.Forms.Timer類似。DispatcherTimer中Tick事件執行是在主線程中進行的。
使用DispatcherTimer時有一點需要註意,因為DispatcherTimer的Tick事件是排在Dispatcher隊列中的,當系統在高負荷時,不能保證在Interval時間段執行,可能會有輕微的延遲,但是絕對可以保證Tick的執行不會早於Interval設置的時間。如果對Tick執行時間準確性高可以設置DispatcherTimer的priority。
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。