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

C# System.Timers.Timer是否在独立线程中运行?,c#,.net,timer,C#,.net,Timer,我试图了解System.Timers.Timer何时引发已用事件,它是在独立线程中引发的吗 下面的示例似乎表明,这三个计时器在各自的线程中独立运行: class Program { static System.Timers.Timer timer = new System.Timers.Timer(); static System.Timers.Timer timer2 = new System.Timers.Timer(); static System.Timers.T

我试图了解
System.Timers.Timer
何时引发已用事件,它是在独立线程中引发的吗

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

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();
    }
}

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


您可以在每个线程中输出
System.Threading.Thread.CurrentThread.ManagedThreadId
,以确定是否正确。

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

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

由于
SynchronizingObject
的默认值为null,因此所有已用事件都将在线程池中处理。因此,这取决于线程池有多满,如果有空闲线程,那么每个经过的事件很可能在单独的线程上并发运行。但是,如果出于某种原因,系统线程池已经被完全使用,则有可能按照计划对已运行事件进行序列化

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


引用:

是的,每次调用经过的线程时,都会在其自己的线程上触发回调

此外,在前一个事件处理程序完成之前,没有任何东西可以阻止已运行事件处理程序的启动。例如,如果计时器每500毫秒触发一次,但运行的事件处理程序代码需要2秒才能完成,则运行的代码可能正在访问相同的资源(非线程安全的对象、文件等)。

这相当复杂。报告说:

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

然后这个:

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

然后这个:

如果将计时器与用户界面元素(如窗体或控件)一起使用,而不将计时器放置在该用户界面元素上,请将包含计时器的窗体或控件指定给SynchronizingObject属性,以便将事件封送至用户界面线程


因此,对于您的问题“它是在独立线程中提出的吗?”没有简单的答案,这取决于许多事情。

是的,它们在不同的线程中运行。
System.Timers.Timer
在内部使用
System.Threading.Timer
(在线程上执行单个回调方法)。请看。所有答案都是正确的,但是我觉得ThreadPool是这里的关键组件。