c计时器是自然多线程的

本文关键字:多线程 自然 计时器 | 更新日期: 2023-09-27 17:59:09

如果我有两个系统计时器分别在10和20s时触发事件,那么对事件函数的调用是多线程的吗?在下面的场景中,我有定时器,它们分别以10秒和12秒的间隔触发事件。应首先调用函数"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

c计时器是自然多线程的

CLR使用专用线程跟踪活动的System.Timers.Timer和System.Threading.Timer计时器。Elapsed事件是在从线程池中提取的另一个线程上引发的。

所以,是的,它们一直在滴答作响,而不会相互影响。您必须非常小心,当Elapsed事件处理程序仍在执行时,很可能会再次调用它。当花费的时间超过间隔时,就会发生这种情况。或者更糟的是,当机器负载很重或者有很多活动的线程池线程时。如果事件处理程序不是线程安全的,这可能会导致很难诊断的故障。几乎从来没有。将计时器的"自动重置"属性设置为false是避免此问题的简单方法。

如果使用System.Threading.Timer或在没有SynchronizingObject的情况下调用System.Timers.Timer,它似乎不会阻塞。

类似的问题:C#计时器是否在一个单独的线程上流逝?

来自System.Timers.Timer文档:

基于服务器的Timer是为在多线程环境中与工作线程一起使用而设计的。服务器计时器可以在线程之间移动以处理引发的Elapsed事件,从而在按时引发事件方面比Windows计时器更准确。

是的。

此外,来自System.Timers.Timer.SynchronizingObject房地产文件:

当SynchronizingObject为null时,将在系统线程池中的线程上调用处理Elapsed事件的方法。有关系统线程池的更多信息,请参阅ThreadPool。

因此,除非设置了SynchronizingObject,否则事件将在线程池线程上引发。