.NET的内建类型中,共提供了3种定时器:
System.Windows.Forms.Timer 类型
System.Threading.Timer 类型
System.Timers.Timer 类型
下面来探讨这三种类型的特点.
System.Windows.Forms.Timer 类型
这个类型是为了方便我们在Windows界面上使用定时器.
当构造一个System.Windows.Forms.Timer类型时,当前定时器会和当前线程进行关联,它并没有涉及多线程的操作,定时器的设置和定时方法的执行都在同一个线程之上.定时器的计时到达之后,一个定时器消息将被插入到当前线程的消息队列中.当前线程逐一处理消息队列中的所有信息,并一一派发给各自的处理方法.
但是,在当前信息过多时,会阻塞线程,使得计时并不准确.
System.Threading.Timer 类型
这个定时器的定时方法将被确定在工作者线程上执行,所有的对象都由一个线程控制.当下一个计时到达时,该线程会负责在线程中获得一个新的工作者线程,用以执行相应的回调方法.
因为是新的工作者线程处理计时,System.Threading.Timer 类型是一个"相对"最优的一个定时器类型.
System.Timers.Timer类型
System.Timers.Timer类型和System.Threading.Timer类型一样,也可以由工作者线程来执行回调方法;也可以在IDE的环境中被拖放到窗体控件上,这时类似于System.Windows.Forms.Timer类型,在消息过多时并不准确,但它不会遗漏回调事件的执行.
.NET内建定时器类型是否会发生回调方法重入
1) 方法重入的概念
程序中多个线程同时运行时,可能发生同一个方法被多个线程同时调用的情况.当这个方法中存在一些非线程安全的代码时,方法重入会导致数据不一致的情况,这是很严重的bug.
2) 定时器是否会放声回调方法重入
System.Windows.Forms.Timer 类型不会发生回调方法重入的情况;
System.Threading.Timer 类型是一种典型的多线程编程环境,是可能发生方法重入的现象的.
System.Timers.Timer类型可通过同步块属性设置同步时,不会发生方法重入的情况;同步块属性未被设定时, 回调方法可能会产生重入的情况.
3) 解决办法
在回调方法中添加lock锁;但是加锁会影响程序的执行效率.所以在编写定时器代码时,应仔细考虑何时需要加锁,何时需要确保多线程并行运行.