.NET中的Timer類型用法詳解
在.NET FrameWork中有多個Timer,那么怎么根據(jù)實(shí)際情況進(jìn)行選擇確實(shí)是一個問題。
總體而言,計(jì)時器共有以下四種:
多線程計(jì)時器:
1 System.Threading.Timer
2 System.Timers.Timer
特殊環(huán)境的單線程計(jì)時器:
1 System.Windows.Forms.Timer(使用環(huán)境:Windows Forms Timer)
2 System.Windows.Threading.DispatcherTimer( 使用環(huán)境:WPF timer);
單線程計(jì)時器比較安全, 因?yàn)檫\(yùn)行在主線程中,對于更新 Windows Forms或者WPF 中控件的值 這種簡單任務(wù)來說更方便。 例如時鐘和計(jì)數(shù)顯示。否則,你需要一個多線程計(jì)時器。
原理:單線程使用消息循環(huán)機(jī)制,這意味著Tick事件總是在創(chuàng)建timer的那個線程上執(zhí)行,同時也意味著如果上一個Tick消息還未被處理,即使時間超過了間隔時間,在消息循環(huán)中也只存在一個Tick消息。
示例代碼如下:
public static void Main() { System.Windows.Forms.Timer tmr = new System.Windows.Forms.Timer(); tmr.Tick += new EventHandler(tmr_Tick); tmr.Start();//開始計(jì)時器 tmr.Stop();//停止計(jì)時器 tmr.Enabled =true;//設(shè)置或獲取計(jì)時器是否正在運(yùn)行 tmr.Interval = 10000; //計(jì)時器的時間間隔 (10秒),以毫秒為單位,在計(jì)時器事件tmr_Tick開始10秒后進(jìn)行第一次執(zhí)行. } void tmr_Tick(object sender, EventArgs e) { //到達(dá)指定時間間隔應(yīng)處理的代碼 }
當(dāng)tmr_Tick執(zhí)行時間較長,UI界面會卡頓,如下圖所示:
多線程計(jì)時器比較強(qiáng)大,精確,而且可擴(kuò)展性強(qiáng);使用多線程計(jì)時器時不會對主線程造成任何影響,也就不會出現(xiàn)上面圖片顯示的情況.
原理:多線程計(jì)時器使用回調(diào)方法并由線程池線程提供服務(wù).當(dāng)計(jì)時器間隔小于執(zhí)行此回調(diào)(Tick方法)所需的時間時,回調(diào)可以同時在多個線程中執(zhí)行,比如當(dāng)計(jì)時器的時間間隔是5秒,但過了5秒后,上一次的回調(diào)仍未完成,此時新的回調(diào)將在新的線程中運(yùn)行.在開發(fā)中需要避免此種情況。
System.Threading.Timer是最簡單的多線程計(jì)時器。
只要在使用 System.Threading.Timer,就必須保留對它的引用。對于任何托管對象,如果沒有對 Timer 的引用,計(jì)時器會被垃圾回收。即使 Timer 仍處在活動狀態(tài),也會被回收。
在下面的例子中,計(jì)時器在5秒后開始定時1秒的調(diào)用Tick方法。
public static void Main() { int duetime = 5000; int period = 1000; System.Threading.Timer timer = new System.Threading.Timer(Tick,"給Tick方法傳的參數(shù),object類型",duetime ,period ); duetime = 10000; period = 2000; //修改等待時間為10秒和間隔時間為2秒 timer.Change(duetime, period); //取消計(jì)時器 timer.Dispose(); } static void Tick(object data) { Console.WriteLine(data); //如果此時需要訪問控件,因?yàn)榛卣{(diào)線程跟主線程是完全不同的兩個線各,因此需要使用Control.Invoke或BeginInvoke方法,來實(shí)現(xiàn),例如: this.BeginInvoke((MethodInvoker)delegate() { this.lbl_w.Text = data.ToString (); }); }
.net framework提供的另一個計(jì)時器System.Timers.Timer.簡單的對System.Threading.Timer進(jìn)行了包裝。增加了下面幾個特性:
1.實(shí)現(xiàn)了Component,所以可以在設(shè)計(jì)器顯示。
2.用Interval屬性代替代替Change方法
3.添加了Elapsed事件, 啟動和停止timer的Start和Stop方法。
4.添加了AutoReset屬性 默認(rèn)為True 來指定是否在每次指定的間隔結(jié)束時引發(fā)Elapsed事件,還是僅運(yùn)行一次Elapsed事件就結(jié)束
示例代碼如下:
public static void MainThread() { System.Timers.Timer Timer tmr=new System.Timers.Timer(); tmr.Interval=500; tmr.Elapsed+=newElapsedEventHandler(tmr_Elapsed); tmr.AutoReset = false; tmr.Start(); Console.ReadLine(); tmr.Stop(); Console.ReadLine(); tmr.Dispose(); } void tmr_Elapsed(objectsender,ElapsedEventArgse) { Console.WriteLine("Tick..."); }
結(jié)論:
WPF和Windows Forms的單線程計(jì)時器都非常適合小任務(wù),尤其是界面更新的任務(wù)。例如時鐘和計(jì)數(shù)顯示。
否則,你只能使用多線程計(jì)時器,對于使用哪一種多線程計(jì)時器,可根據(jù)自己的需要來決定
希望本文所述對大家掌握.net中timer的用法有所幫助。
相關(guān)文章
C#遞歸遍歷窗體所有textbox控件并設(shè)置textbox事件的方法
這篇文章主要介紹了C#遞歸遍歷窗體所有textbox控件并設(shè)置textbox事件的方法,包括針對textbox控件的遞歸遍歷技巧與事件方法的設(shè)置技巧,需要的朋友可以參考下2014-12-12HttpWebRequest出錯.Section=ResponseHeader Detail=CR
HttpWebRequest出錯.Section=ResponseHeader Detail=CR...2007-03-03C#實(shí)現(xiàn)SQL批量插入數(shù)據(jù)到表的方法
這篇文章主要介紹了C#實(shí)現(xiàn)SQL批量插入數(shù)據(jù)到表的方法,涉及C#批量操作SQL的相關(guān)技巧,需要的朋友可以參考下2016-04-04C#從windows剪貼板獲取并顯示文本內(nèi)容的方法
這篇文章主要介紹了C#從windows剪貼板獲取并顯示文本內(nèi)容的方法,涉及C#操作剪貼板的相關(guān)技巧,非常具有實(shí)用價值,需要的朋友可以參考下2015-04-04C#實(shí)現(xiàn)通過程序自動抓取遠(yuǎn)程Web網(wǎng)頁信息的代碼
C#實(shí)現(xiàn)通過程序自動抓取遠(yuǎn)程Web網(wǎng)頁信息的代碼...2007-04-04C#實(shí)現(xiàn)獲取枚舉中元素個數(shù)的方法
這篇文章主要介紹了C#實(shí)現(xiàn)獲取枚舉中元素個數(shù)的方法,是深入理解C#程序設(shè)計(jì)所需要掌握的基本技巧,需要的朋友可以參考下2014-08-08