计时器
2種專(zhuān)用單線程計(jì)時(shí)器
System.Windows.Forms.Timer (Windows Forms timer)
System.Windows.Threading.DispatcherTimer (WPF timer) 多線程計(jì)時(shí)器更加精確靈活,單線程計(jì)時(shí)器更安全和方便,特別是對(duì)于簡(jiǎn)單的任務(wù)比如更新窗體控件之類(lèi)的。 System.Threading.Timer是最簡(jiǎn)單的多線程計(jì)時(shí)器:它只有一個(gè)構(gòu)造器和2個(gè)方法。看下面的例子。一個(gè)計(jì)時(shí)器5秒后調(diào)用Tick方法,然后每秒調(diào)用一次,直到用戶按回車(chē)。 static void Main() { // First interval = 5000ms; subsequent intervals = 1000ms Timer tmr = new Timer(Tick, "tick...", 5000, 1000); Console.ReadLine(); tmr.Dispose(); // This both stops the timer and cleans up. } static void Tick(object data) { // This runs on a pooled thread Console.WriteLine(data); // Writes "tick..." } 你可以改變間隔時(shí)間,如果你只想調(diào)用一次,只需指定Timeout.Infinite作為構(gòu)造方法的最后一個(gè)參數(shù)。 .NET Framework提供另一個(gè)計(jì)時(shí)器類(lèi)。它簡(jiǎn)單包裹了System.Threading.Timer,并且額外提供一些功能: 是一個(gè)控件 Interval屬性代替了Change方法 Elapsed事件代替了回調(diào)委托 Enabled屬性來(lái)啟動(dòng)和停止計(jì)時(shí)器 Start和Stop方法,如果你被Enabled屬性混淆了的話 AutoReset標(biāo)志表示一個(gè)循環(huán)事件 一個(gè)SynchronizingObject屬性帶有Invoke和BeginInvoke方法,用來(lái)安全的調(diào)用WPF元素和Windows Form控件。 看下面的例子。 using System; using System.Timers; // Timers namespace rather than Threading class Program { static void Main() { Timer tmr = new Timer(); // Doesn't require any args tmr.Interval = 500; tmr.Elapsed += tmr_Elapsed; // Uses an event instead of a delegate tmr.Start(); // Start the timer Console.ReadLine(); tmr.Stop(); // Stop the timer Console.ReadLine(); tmr.Start(); // Restart the timer Console.ReadLine(); tmr.Dispose(); } static void tmr_Elapsed(object sender, EventArgs e) { Console.WriteLine("Tick"); } }多線程計(jì)時(shí)器使用的是線程池,這意味著回調(diào)方法或者Tick事件可能每次由不同的線程調(diào)用,此外,每次都很準(zhǔn)時(shí),不管先前一次Tick是否已經(jīng)執(zhí)行完成。因此回調(diào)或者事件必須是線程安全的。
多線程timer的精確性依靠于操作系統(tǒng),通常有10-20ms的誤差。如果想要更高級(jí)別的精確性,你就需要用本地interop,并且調(diào)用Windows multimedia timer。這個(gè)的精確性在1ms之內(nèi),它定義在winmm.dll中。
NET Framework 提供了計(jì)時(shí)器來(lái)為WPF和Winform消除線程安全問(wèn)題。
? System.Windows.Threading.DispatcherTimer (WPF)
? System.Windows.Forms.Timer (Windows Forms)
單線程Timer應(yīng)該在他們各自的環(huán)境中運(yùn)行,如果你使用Winform計(jì)時(shí)器在Windows ?Service Application,Timer事件不會(huì)被觸發(fā)。
這些類(lèi)暴露出來(lái)的方法和System.Timers.Timer的用法相似,但是不同在于內(nèi)部的執(zhí)行原理。不是使用線程池產(chǎn)生計(jì)時(shí)器事件,WPF和WinForm計(jì)時(shí)器依靠消息泵機(jī)制來(lái)作為他們的接口模型。這意味著Tick事件總是觸發(fā)在初始創(chuàng)造這個(gè)計(jì)時(shí)器的線程上,在通常的應(yīng)用程序中,也是同一個(gè)線程管理用戶接口元素和控件的。這樣設(shè)計(jì)有很多好處:
不需要在擔(dān)心線程安全
前一個(gè)Tick不完成,后一個(gè)Tick不開(kāi)始。
可以在Tick事件中直接更新用戶控件,而不需要Control.Invoke或者Dispatcher.Invoke。
聽(tīng)起來(lái)都不錯(cuò),但是程序使用此類(lèi)計(jì)時(shí)器不是真正的多線程,沒(méi)有并行執(zhí)行,一個(gè)線程服務(wù)于所以的計(jì)時(shí)器,包括UI事件。這就有缺點(diǎn),除非Tick事件處理的很快,不然的話用戶界面可能無(wú)響應(yīng)。
這些控件適合在WPF和WinForm中的小工作,比如更新用戶界面方面,類(lèi)似時(shí)鐘,倒計(jì)時(shí)等。不然,你還是需要一個(gè)多線程計(jì)時(shí)器,在精確性方面,單線程Timer和多線程Timer類(lèi)似,10ms左右,盡管單線程Timer稍微不如多線程Timer精確,這是因?yàn)樗鼈兛赡苡捎谟脩艚缑嬲?qǐng)求或者Timer事件處理而延遲。
?
?
?
?
?
?
本文轉(zhuǎn)自cnn23711151CTO博客,原文鏈接:http://blog.51cto.com/cnn237111/536247?,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者
總結(jié)
- 上一篇: 删除有序链表中的重复结点
- 下一篇: Spring自定义注解简单使用四步走