首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >System.Timers.Timer是否在独立线程中运行?

System.Timers.Timer是否在独立线程中运行?
EN

Stack Overflow用户
提问于 2011-10-26 02:06:15
回答 4查看 24.7K关注 0票数 20

我试图理解当System.Timers.Timer引发elapsed事件时,它是在一个独立的线程中引发的吗?

我下面的例子似乎表明这三个计时器在各自的线程中独立运行:

代码语言:javascript
复制
class Program
{
    static System.Timers.Timer timer = new System.Timers.Timer();
    static System.Timers.Timer timer2 = new System.Timers.Timer();
    static System.Timers.Timer timer3 = new System.Timers.Timer();

    static void Main(string[] args)
    {
        timer.Elapsed += new System.Timers.ElapsedEventHandler(
            timer_Elapsed);
        timer2.Elapsed += new System.Timers.ElapsedEventHandler(
            timer2_Elapsed);
        timer3.Elapsed += new System.Timers.ElapsedEventHandler(
            timer3_Elapsed);

        timer.Interval = 1000;
        timer2.Interval = 1000;
        timer3.Interval = 1000;

        timer.Start();
        timer2.Start();
        timer3.Start();

        Console.WriteLine("Press \'q\' to quit the sample.");
        while (Console.Read() != 'q') ;
    }

    static void timer3_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        timer3.Stop();
        Console.WriteLine("Timer 3 Hit...");            
        timer3.Start();
    }

    static void timer2_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        timer2.Stop();
        Console.WriteLine("Timer 2 Hit...");
        Thread.Sleep(2000);
        timer2.Start();
    }

    static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        timer.Stop();
        Console.WriteLine("Timer 1 Hit...");
        Thread.Sleep(10000);
        timer.Start();
    }
}

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-10-26 02:14:52

根据MSDN的说法,在System.Timers.Timer上,当Elapsed事件触发时,它是在系统线程池中的线程上调用的:

如果SynchronizingObject属性为Nothing,则在ThreadPool线程上引发Elapsed事件。如果对已用事件的处理持续时间超过时间间隔,则可能会在另一个ThreadPool线程上再次引发该事件。在这种情况下,事件处理程序应该是可重入的。

由于SynchronizingObject的缺省值为null,因此所有已用事件都将在线程池中处理。因此,这取决于线程池有多满,如果有空闲线程,那么每个已用事件很可能在单独的线程上并发运行。但是,如果由于某种原因,系统线程池已经完全在使用,则可能会在调度事件时序列化已用事件。

要点是:“视情况而定。”也就是说,只要池中有空闲线程,它们就可以并行运行。

参考:MSDN on System.Timers.Timer

票数 24
EN

Stack Overflow用户

发布于 2011-10-26 02:12:51

根据您的代码,它们必须是,因为Thread.Sleep是一个阻塞调用。如果其他计时器在同一线程上运行,则它们都不会触发。

你可以在每一个文件中输出System.Threading.Thread.CurrentThread.ManagedThreadId来确认。

票数 5
EN

Stack Overflow用户

发布于 2011-10-26 02:19:48

这很复杂。documentation说明如下:

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

然后是这个:

如果SynchronizingObject属性为null,则在ThreadPool线程上引发Elapsed事件。如果对已用事件的处理持续时间超过时间间隔,则可能会在另一个ThreadPool线程上再次引发该事件。在这种情况下,事件处理程序应该是可重入的。

然后是这个:

如果将Timer与用户界面元素(如窗体或控件)一起使用,而没有将timer放置在该用户界面元素上,请将包含该Timer的窗体或控件分配给SynchronizingObject属性,以便将该事件封送到用户界面线程。

因此,对于您的问题“它是在独立线程中引发的吗?”没有简单的答案。这取决于很多东西。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7893773

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档