.net Timer 比较

来源:互联网 发布:如何优化公司人力成本 编辑:程序博客网 时间:2024/05/17 13:40

    在 Win32 体系结构中有两种类型的线程:UI 线程和辅助线程。UI 线程绝大多数时间处于空闲状态,等待消息循环中的消息到来。一旦接收到消息,它们就进行处理并等待下一个消息到来。另外,辅助线程用来执行后台处理而且不使用消息循环。Windows计时器和基于服务器的计时器在运行时都使用 Interval属性。线程计时器的时间间隔在 Timer构造函数中设置。计时器的设计目的各不相同,它们的线程处理明确地指出了这一点:

 

1.      System.Windows.Forms.Timer

实现按用户定义的时间间隔引发事件的计时器。此计时器最宜用于 Windows窗体应用程序中,并且必须在窗口中使用。 

Timer 用于以用户定义的事件间隔触发事件。Windows计时器是为单线程环境设计的,其中,UI线程用于执行处理。它要求用户代码有一个可用的 UI消息泵,而且总是在同一个线程中操作,或者将调用封送到另一个线程。

Windows 窗体 Timer组件是单线程组件,精度限定为 55毫秒。如果您需要更高精度的多线程计时器,请使用System.Timers命名空间中的 Timer类。

由于此Timer执行事件(Tick)占用时间为UI线程时间,只建议执行非常短UI界面操作。

附注:有人建议此Tick大概执行需要在30ms以内。否则对界面响应可能有影响。

 

http://msdn.microsoft.com/zh-cn/library/system.windows.forms.timer.aspx

 

2.      System.Timers.Timer 

在应用程序中生成定期事件。 

Timer 组件是基于服务器的计时器,它使您能够指定在应用程序中引发Elapsed 事件的周期性间隔。然后可通过处理这个事件来提供常规处理。

基于服务器的 Timer 是为在多线程环境中用于辅助线程而设计的。服务器计时器可以在线程间移动来处理引发的Elapsed 事件,这样就可以比Windows 计时器更精确地按时引发事件。

如果SynchronizingObject 属性为 null,则在 ThreadPool 线程上引发 Elapsed 事件。如果 Elapsed 事件的处理时间比 Interval 长,在另一个 ThreadPool 线程上将会再次引发此事件。在这种情况下,事件处理程序应当是可重入的。

 

http://msdn.microsoft.com/zh-cn/library/system.timers.timer.aspx

 

 

3.      System.Threading.Timer 

提供以指定的时间间隔执行方法的机制。无法继承此类。 

使用 TimerCallback 委托指定希望 Timer 执行的方法。计时器委托在构造计时器时指定,并且不能更改。此方法不在创建计时器的线程上执行,而是在系统提供的 ThreadPool线程上执行。

创建计时器时,可以指定在第一次执行方法之前等待的时间量(截止时间)以及此后的执行期间等待的时间量(时间周期)。可以使用 Change方法更改这些值或禁用计时器。

只要在使用 Timer,就必须保留对它的引用。对于任何托管对象,如果没有对 Timer的引用,计时器会被垃圾回收。即使 Timer仍处在活动状态,也会被回收。

System.Threading.Timer 是一个简单的轻量计时器,它使用回调方法并由线程池线程提供服务。不建议将其用于 Windows窗体,因为其回调不在用户界面线程上进行。

 

http://msdn.microsoft.com/zh-cn/library/system.threading.timer.aspx

 

三种Timer的比较

 

适合

执行线程

需要Windows窗体?

支持State对象?

支持继承?

初始等待时间?

精度

System.Windows.Forms.Timer

单线程

UI线程

55ms

System.Timers.Timer

多线程

UI/ThreadPool 线程

更精确?

System.Threading.Timer

多线程

ThreadPool 线程

 

 

小结:如果界面相关使用,推荐使用System.Timers.Timer。而如果后台使用,尤其是需要大数量的Timer时,推荐使用System.Threading.Timer

 

         由于MSDN 推荐,如果需要精确性更高的Timer,就不要选System.Windows.Forms.Timer,而用System.Timers.Timer或者System.Threading.Timer,编了一个小程序测试各种Timer的时间精确性。

三种Timer时间精确性的测试

 

5000ms/100次

1000ms/100次

100ms/100次

20ms/100次

1ms/100次

System.Windows.Forms.Timer

500750

101384

10920

3110

1550

System.Timers.Timer

500745

101368

10904

3100

1550

System.Threading.Timer

500746

101384

10904

3110

1540

 

代码Demo:Timer Demo

         测试结果,发现三种Timer时间精确性差不多。在以秒级别时间间隔(或者更高的分钟等),还能凑合使用(前提是对时间精度要求不高),如果时间精度要求非常高,可以使用下面的dll。

 

[DllImport("winmm.dll")]

       private staticextern inttimeSetEvent(int delay,int resolution,

            TimeProc proc, int user, int mode);

 

这个能达到 1ms

原创粉丝点击