.net 定时器
.net的FCL中有以下3个定时器:
(1) Windows.Forms.Timer
(2) Timers.Timer
(3) System.Threading.Timer
其实定时器只有两个,Forms下的Timer和Threading下的Timer,Timers中的Timer是对线程中的Timer封装。
区别:
windows窗体中的定时器,是基于UI主线程的定时器,单线程处理的 。个人认为就是窗体的一个定时器消息。定时器的处理回调由定时器所在的主线程完成。
如果当前winform程序主线程正在被挂起,那么后续的Timer的回调事件将不能被处理直到主线程恢复。Threading的Timer,是基于.net的ThreadingPool的。Timer的回调都将被放入 线程池等待处理,回调函数是可重入的。虽然说他是多线程处理的,但是同样存在一样的问题。因为此Timer基于线程池。如果线程池当前的线程全部被占用并一直出于执行状态,无可用线程。Timer的回调同样将不会得到及时的处理直到线程池中有空闲的线程来处理线程池的工作项。所以当在用Threading空间下的Timer的时候,而程序中可能又频繁的使用线程池或者设定了线程池大小的时候需要注意了。
在测试上述的两个定时器的时候,发现个我以前没考虑到的方面。如果我在主线程池中显示一个模态的对话框其实并没用阻塞主线程,主线程而是切换到了显示模态显示的对话框中,成为莫泰对话框的主线程(网上看到的,不知是否真的如此),所以这种情况,Windows下的Timer依然可以正常运行。