1

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

这是为什么?

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

4

2 回答 2

3

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

于 2016-07-13T19:06:07.617 回答
1

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

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

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

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

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

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

于 2016-07-13T19:08:23.257 回答