如果我有两个系统定时器分别在10和20s触发事件,那么对事件函数的调用是多线程的吗?在下面的场景中,我有定时器,分别以10和12s的间隔触发事件。期望首先调用函数'My10sEvent'。如果它是一个需要8秒钟才能运行的慢速功能,它会阻止另一个事件(tmr12s),还是第二个事件会在12秒时触发?
System.Timers.Timer tmr10s = new System.Timers.Timer(10000.0);
tmr10s.Enabled = true;
tmr10s.Elapsed += new ElapsedEventHandler(My10sEvent);
System.Timers.Timer tmr12s = new System.Timers.Timer(12000.0);
tmr12s.Enabled = true;
tmr12s.Elapsed += new ElapsedEventHandler(My12sEvent);
Thread.Sleep(System.Threading.Timeout.Infinite); //sleep indefinitely to let the above events fire
答案 0 :(得分:4)
CLR使用专用线程来跟踪活动的System.Timers.Timer和System.Threading.Timer计时器。 Elapsed事件是在从线程池中拉出的另一个线程上引发的。
所以是的,他们不停地打勾而不会相互影响。你必须非常小心,你的Elapsed事件处理程序很可能在它仍在执行时再次被调用。当它花费的时间超过间隔时会发生这种情况。或者更糟糕的是,当机器负载很重或者你有很多活动的线程池线程时。如果您的事件处理程序不是线程安全的,这可能会导致很难诊断失败。它几乎从来都不是。将计时器的AutoReset属性设置为false是避免此问题的简单方法。
答案 1 :(得分:3)
如果您使用System.Threading.Timer或在没有SynchronizingObject的情况下调用System.Timers.Timer,它看起来不会阻塞。
答案 2 :(得分:1)
来自System.Timers.Timer
文档:
基于服务器的Timer设计用于多线程环境中的工作线程。服务器计时器可以在线程之间移动以处理引发的Elapsed事件,从而在准时引发事件时比Windows计时器更准确。
是的,是的。
此外,来自System.Timers.Timer.SynchronizingObject
属性文档:
当SynchronizingObject为null时,将在系统线程池的线程上调用处理Elapsed事件的方法。有关系统线程池的更多信息,请参阅ThreadPool。
因此,除非设置了SynchronizingObject,否则会在线程池线程上引发事件。