C#中有5个timer,它们的主要区别如下:
- System.Threading.Timer 在线程池启动一个后台任务。我前段时间写过一个关于timer的垃圾回收的需要注意一下,参见谁动了我的timer?。
- System.Windows.Forms.Timer 告诉windows把一个计时器和调用它的线程(UI线程)关联起来,通过往UI线程的消息队列里放一个WM_TIMER的消息来实现,所以它的callback一定是在UI线程调用的,不存在多线程调用的问题。
- System.Windows.Threading.DispatcherTimer 用在WPF和Silverlight中,对应于System.Windows.Forms.Timer。
- Windows.UI.Xaml.Dispatchertimer 用在windows store app中,对应于System.Windows.Forms.Timer。
- System.Timers.Timer 包装了一下System.Threading.Timer,使它有了和System.Windows.Forms.Timer类似的接口,而且也能在visual studio的toolbox designer里找到。它也是在线程池中执行,但是如果你是在visual studio的designer中使用它,visual studio会自动把它所在的control设为这个timer的SynchronizingObject,这样就会保证callback会在UI线程调用了。Jeffrey Richter不建议使用它,建议直接用System.Threading.Timer。这个timer也有个坑,参见.NET 2.0的Timer elapsed event 会自动catch住所有的exception。
Comparing the Timer Classes in the .NET Framework Class Library也比较了3中timer(System.Threading.Timer ,System.Windows.Forms.Timer和System.Timers.Timer),并且画了个如下的表格。
System.Windows.Forms | System.Timers | System.Threading | |
Timer event runs on what thread? | UI thread | UI or worker thread | Worker thread |
Instances are thread safe? | No | Yes | No |
Familiar/intuitive object model? | Yes | Yes | No |
Requires Windows Forms? | Yes | No | No |
Metronome-quality beat? | No | Yes* | Yes* |
Timer event supports state object? | No | No | Yes |
Initial timer event can be scheduled? | No | No | Yes |
Class supports inheritance? | Yes | Yes | No |
* Depending on the availability of system resources (for example, worker threads) |