Reputation:
If I have two system timers firing events at 10 and 20s respectively, are the calls to the event functions multithreaded? In the scenario below, I have timers that fire events at 10 and 12s intervals respectively. The function 'My10sEvent' is expected to be called first. If it is a slow function that takes 8 seconds to run, will it block the other event (tmr12s), or will the second event fire on time at 12s?
System.Timers.Timer tmr10s = new System.Timers.Timer(10000.0);
tmr10s.Enabled = true;
tmr10s.Elapsed += new ElapsedEventHandler(My10sEvent);
System.Timers.Timer tmr12s = new System.Timers.Timer(12000.0);
tmr12s.Enabled = true;
tmr12s.Elapsed += new ElapsedEventHandler(My12sEvent);
Thread.Sleep(System.Threading.Timeout.Infinite); //sleep indefinitely to let the above events fire
Upvotes: 3
Views: 4563
Reputation: 941327
The CLR uses a dedicated thread to keep track of active System.Timers.Timer and System.Threading.Timer timers. The Elapsed event is raised on another thread pulled from the threadpool.
So yes, they keep ticking without affecting each other. You have to be very careful, it is quite possible for your Elapsed event handler to be called again while it is still executing. Which happens when it takes longer than the interval. Or worse, when the machine is heavily loaded or you have a lot of active threadpool threads. This can cause very hard to diagnose failure if your event handler isn't thread-safe. It almost never is. Setting the timer's AutoReset property to false is a simple way to avoid this problem.
Upvotes: 5
Reputation: 22415
Looks like it won't block if you use System.Threading.Timer or invoke System.Timers.Timer without a SynchronizingObject.
Similar question: Do C# Timers elapse on a separate thread?
Upvotes: 3
Reputation: 22673
From the System.Timers.Timer
documentation:
The server-based Timer is designed for use with worker threads in a multithreaded environment. Server timers can move among threads to handle the raised Elapsed event, resulting in more accuracy than Windows timers in raising the event on time.
So yes, it is.
Futhermore, from the System.Timers.Timer.SynchronizingObject
property documentation:
When SynchronizingObject is null, the method that handles the Elapsed event is called on a thread from the system-thread pool. For more information on system-thread pools, see ThreadPool.
So the events are raised on thread pool threads unless SynchronizingObject is set.
Upvotes: 1