C#四種計時器Timer的區(qū)別和用法
1、System.Threading.Timer 線程計時器
1、最底層、輕量級的計時器。基于線程池實現(xiàn)的,工作在輔助線程。
2、它并不是內在線程安全的,并且使用起來比其他計時器更麻煩。此計時器通常不適合 Windows 窗體環(huán)境。
構造函數(shù):public Timer(TimerCallback callback, object state, int dueTime, int period);
string state=”.”; //state參數(shù)可以傳入想在callback委托中處理的對象??梢詡鬟f一個AutoRestEvent,在回調函數(shù)中向主函數(shù)發(fā)送信號。 Timer timer=new Timer(TimeMethod,state,100,1000)//100表示多久后開始,1000表示隔多久執(zhí)行一次。 void TimerMethod(object state) {Console.Write(state.ToString());} timer.Dispose();//取消timer執(zhí)行
2、System.Timers.Timer 服務器計時器
1、針對服務器的服務程序,基于System.Threading.Timer,被設計并優(yōu)化成能用于多線程環(huán)境。在這種情況下,應該確保事件處理程序不與 UI 交互。在asp.net中一般使用System.Timers.Timer。
2、繼承自Compnent,公開了可以SynchronizingObject 屬性,避免了線程池中無法訪問主線程中組件的問題(模擬System.Windows.Forms.Timer單線程模式)。但是除非需要對事件的時間安排進行更精確的控制,否則還是應該改為使用 System.Windows.Forms.Timer。
3、AutoReset屬性設置計時器是否在引發(fā)Elapsed事件后重新計時,默認為true。如果該屬性設為False,則只執(zhí)行timer_Elapsed方法一次。
4、System.Timers.Timer是多線程定時器,如果一個Timer沒有處理完成,到達下一個時間點,新的Timer同樣會被啟動。所以,Timer比較適合執(zhí)行不太耗時的小任務,若在Timer中運行耗時任務,很容易出現(xiàn)由于超時導致的多線程重入問題,即多個線程同時進入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、為了應對多線程重入問題??梢约渔i,也可以增加標志位。 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,它經(jīng)過了專門的優(yōu)化以便與 Windows 窗體一起使用,并且必須在窗口中使用。
- Windows計時器建立在基于消息的UI線程上運行,精度限定為5ms。Tick事件中執(zhí)行的事件與主窗體是同一個線程(單線程),并且對與 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事件執(zhí)行是在主線程中進行的。
使用DispatcherTimer時有一點需要注意,因為DispatcherTimer的Tick事件是排在Dispatcher隊列中的,當系統(tǒng)在高負荷時,不能保證在Interval時間段執(zhí)行,可能會有輕微的延遲,但是絕對可以保證Tick的執(zhí)行不會早于Interval設置的時間。如果對Tick執(zhí)行時間準確性高可以設置DispatcherTimer的priority。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
UGUI ScrollRect實現(xiàn)帶按鈕翻頁支持拖拽
這篇文章主要為大家詳細介紹了UGUI ScrollRect實現(xiàn)帶按鈕翻頁支持拖拽,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-05-05在Parallel中使用DbSet.Add()發(fā)現(xiàn)的一系列多線程問題和解決思路詳解
這篇文章主要介紹了在Parallel中使用DbSet.Add()發(fā)現(xiàn)的一系列多線程問題和解決過程的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-11-11C# mysql 插入數(shù)據(jù),中文亂碼的解決方法
用C#操作mysql時, 插入數(shù)據(jù)中文都是亂碼,只顯示問號,數(shù)據(jù)庫本身使用的是utf-8字符2013-10-10C#通過創(chuàng)建Windows服務啟動程序的方法詳解
這篇文章主要介紹了C#通過創(chuàng)建Windows服務啟動程序的方法,較為詳細的分析了C#創(chuàng)建Windows服務應用程序的步驟與相關注意事項,需要的朋友可以參考下2016-06-06C#使用AutoUpdater.NET實現(xiàn)程序自動更新
開發(fā)桌面應用程序的時候,經(jīng)常會因為新增功能需求或修復已知問題,要求客戶更新應用程序,在.Net體系中采用?AutoUpdater.NET?組件可以非常便捷的實現(xiàn)這一功能,需要的朋友可以參考下2024-02-02