简体   繁体   中英

Why does System.Timers.Timer create multiple threads when it fires the Elapsed events?

When I create a System.Timers.Timer such as...

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 + "]");
}

Results with interval set to 1000:

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

Results with interval set to 2000:

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

I see that the Elapsed event is showing different threads when it is firing. Although when I change the Interval value to something higher such as 2000 (instead of the 1000) it seems to stay on the same thread.

Why is that?

I'm wanting a timer that fires on it's own thread but just fires on the one thread and not multiple threads.

It uses the thread pool to execute the handlers. Depending on what your program is doing, your thread pool might have one thread in it, or many, and you may or may not have different threads handling any given request.

It does it because that's the way it was written.

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

The server-based System.Timers.Timer class is designed for use with worker threads in a multithreaded environment. Server timers can move among threads to handle the raised Elapsed event . . .

FWIW, Microsoft recommends that you not use it:

The Timer class is available in the .NET Framework only. It is not included in the .NET Standard Library and is not available on other platforms, such as .NET Core or the Universal Windows Platform. On these platforms, as well as for portability across all .NET platforms, you should use the System.Threading.Timer class instead.

The Timer class is now available in the .NET Standard Library as of .NET Standard 2.0. Obviously, the comment above was correct when it was written...3+ years ago. If you need to go back to .Net Standard Version 1.6 or sooner, then YES, the above comment is accurate.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM