为什么System.Timers.Timer在触发已用事件时会创建多个线程

本文关键字:事件 创建 线程 Timers System Timer 为什么 | 更新日期: 2023-09-27 17:56:44

当我创建一个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)时,它似乎保持在同一线程上。

为什么?

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

为什么System.Timers.Timer在触发已用事件时会创建多个线程

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

它这样做是因为这就是它的编写方式。

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

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

。 。

FWIW,Microsoft建议您不要使用它:

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

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