为啥 System.Timers.Timer 在触发 Elapsed 事件时会创建多个线程?

Posted

技术标签:

【中文标题】为啥 System.Timers.Timer 在触发 Elapsed 事件时会创建多个线程?【英文标题】:Why does System.Timers.Timer create multiple threads when it fires the Elapsed events?为什么 System.Timers.Timer 在触发 Elapsed 事件时会创建多个线程? 【发布时间】:2016-11-16 12:25:12 【问题描述】:

当我创建一个System.Timers.Timer 时...

private System.Timers.Timer m_checker = new System.Timers.Timer();
public MyClass()

    Debug.WriteLine("[threadid:" + Thread.CurrentThread.ManagedThreadId + "] Main Thread");
    m_checker.Elapsed += m_checker_Elapsed;
    m_checker.Interval = 1000;
    m_checker.Start();


private void m_checker_Elapsed(object sender, System.Timers.ElapsedEventArgs e)

    Debug.WriteLine("[threadid:" + Thread.CurrentThread.ManagedThreadId + "]");

间隔设置为 1000 的结果:

/*
[threadid:10] Main Thread
[threadid:7]
[threadid:7]
[threadid:7]
[threadid:12]
[threadid:7]
[threadid:12]
etc...
*/

间隔设置为 2000 的结果:

/*
[threadid:10] Main Thread
[threadid:7]
[threadid:7]
[threadid:7]
[threadid:7]
etc...
*/

我看到Elapsed 事件在触发时显示了不同的线程。虽然当我将 Interval 值更改为更高的值,例如 2000(而不是 1000)时,它似乎停留在同一个线程上。

这是为什么呢?

我想要一个在它自己的线程上触发但只在一个线程而不是多个线程上触发的计时器。

【问题讨论】:

【参考方案1】:

它使用线程池来执行处理程序。根据您的程序正在执行的操作,您的线程池中可能有一个或多个线程,您可能有也可能没有不同的线程来处理任何给定的请求。

【讨论】:

感谢您的洞察力以及Servy! +1【参考方案2】:

它这样做是因为它是这样写的。

https://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx

基于服务器的 System.Timers.Timer 类设计用于多线程环境中的工作线程。服务器计时器可以在线程之间移动以处理引发的 Elapsed 事件。 . .

FWIW,微软建议你不要使用它:

Timer 类仅在 .NET Framework 中可用。它不包含在 .NET 标准库中,并且在其他平台上不可用,例如 .NET Core 或通用 Windows 平台。在这些平台上,以及跨所有 .NET 平台的可移植性,您应该改用 System.Threading.Timer 类。

Timer 类现在在 .NET Standard 库中可用,从 .NET Standard 2.0 开始。显然,上面的评论在……3 年前写的时候是正确的。如果您需要回到 .Net Standard Version 1.6 或更早版本,那么是的,以上评论是准确的。

【讨论】:

罗杰。那么 System.Threading.Timer 类会以不同方式或相同方式处理它吗? 这也是多线程的。不知何故有问题吗?如果可以使用,System.Windows.Forms.Timer 是单线程的。 是的,这对我来说是个问题。在我的情况下,计时器正在检查和编辑共享内存空间。当 thread1 上的计时器读取内存并开始工作时,thread2 上的计时器启动并在 thread1 完成之前读取。所以他们读取相同的变量值。如果时机恰到好处,这有点疯狂,就像第二个线程计数器充当第一个线程一样...... :) 我只是以为我做错了什么。现在我知道发生了什么,我可以对代码进行更改以解决它。谢谢!

以上是关于为啥 System.Timers.Timer 在触发 Elapsed 事件时会创建多个线程?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 System.Timers.Timer 在触发 Elapsed 事件时会创建多个线程?

System.Timers.Timer 与 System.Threading.Timer

System.Timers.Timer 严重不准确

使用System.Timers.Timer类实现程序定时执行

System.Timers.Timer

System.Windows.Forms.TimerSystem.Timers.TimerSystem.Threading.Timer