三個定時器分別是
- 實現按用戶定義的時間間隔引發事件的計時器。此計時器最宜用於 Windows 窗體應用程序中,並且必須在窗口中使用。
System.Windows.Forms.Timer - 提供以指定的時間間隔執行方法的機制。無法繼承此類。
System.Threading.Timer - 在應用程序中生成定期事件。
System.Timers.Timer
Forms.Timer
這個timer跟js中的定時器道理相同,它並不開辟一個線程,它只是把事件加入到隊列中,它用的是UI線程。所以它的好處就是輕便簡單。因為沒有實體不消耗資源,所以這個timer無法回收。窗體timer和線程timer、計時器timer不同,因為后兩者dispose之后,GC可以收集,而前者無法收集。
使用這個Forms.Timer不能執行IO,網絡請求等耗時操作,否則阻礙UI線程,界面卡住不動。
Timers.Timer和Threading.Timer都會開辟線程。
Timers.Timer
System.Timers.Timer只要處於活動狀態,就會一直存在下去,直到你手工停止或宿主線程結束。MSDN上還有這樣一段話“Elapsed 事件在 ThreadPool 線程上引發。如果 Elapsed 事件的處理時間比 Interval 長,在另一個 ThreadPool 線程上將會再次引發此事件。因此,事件處理程序應當是可重入的。”也就是說,在你在每次的Elapsed 事件處理在下一次輪循時間到來的時候還沒有結束,Timer對象仍然會另一個線程中啟動Elapsed 的處理事件。這種機制的后果就可能會導致你的Timer已經被結束了,但是還會再執行Elapsed事件,MSDN的原文:“在一個線程調用 Stop 方法或將Enabled 屬性設置為 false 的同時,可在另一個線程上運行事件處理方法。這可能導致在計時器停止之后引發 Elapsed 事件。”針對這種情況,如果你不願讓它發生,你可能就必須做一些額外的工作來避免它的發生。這種機制同樣也適用於System.Threading.Timer。
Threading.Timer
System.Threading.Timer : MarshalByRefObject, IDisposable 這是一種輕量經的計時數,它在使用上與System.Timers.Timer的不同表現在:使用回調機制,而不是事件機制。構造器中可以指定首次執行時間(構建后或修改后開始算)和間隔執行時間,這兩個時間(dueTime,period)可以是不同的。它是沒有開始和結束控制接口,從構建開始算,直至釋放結束。它基於ThreadPool線程機制,遵循着上述System.Timers.Timer的相同原則(紅色部分)。同時它在生命周期方面也有必須要注意的地方,它沒有開始或停止(有釋放接口Dispose)方法。在它的生命周期中,必須被其它對象所引用。一旦它不被任何對象所引用,那么就意味着這個Timer對象變成一個不可達對象,會被GC回收。MSDN原文解釋:
“只要在使用 Timer,就必須保留對它的引用。對於任何托管對象,如果沒有對 Timer 的引用,計時器會被垃圾回收。即使 Timer 仍處在活動狀態,也會被回收。”