3

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
  • 1
    I don't think it will block.. Anyway, I don't mean to be rude, but is it really that hard to check for yourself? – Dyppl Jun 14 '11 at 05:49
  • 2
    No you are not being rude at all. I could indeed check it myself (and am doing so), but I find the community here often gives wonderful insight in addition to simple answers :) –  Jun 14 '11 at 05:52
  • yes, that's a valid point and I understand. Sometimes I just get a feeling that people use SO when plain old google or C# compiler would suffice, and the way your question was phrased (basically, yes or no) made it look like one of these "too lazy to launch a VS" questions – Dyppl Jun 14 '11 at 06:02

3 Answers3

5

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.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Why does CLR need dedicated thread? Could you explain some more please? – Ivan Danilov Jun 14 '11 at 06:28
  • Because it needs to know when to start a threadpool thread to call the Elapsed event. This stuff doesn't happen automagically. The logic is simple, it just scans the list for the timer that's due next and sleeps that long. – Hans Passant Jun 14 '11 at 06:46
  • AFAIK there's kernel timer object and CLR's functionality is based upon it. And that kernel object certainly doesn't need separate thread to wait on. I can't say for sure how CLR is implemented internally of course, but having a thread just to receive timer's notifications is a waste. – Ivan Danilov Jun 14 '11 at 06:51
  • You can see the implementation in the SSCLI20 source code. Still works that way, you can see the thread getting started with the debugger in mixed mode. – Hans Passant Jun 14 '11 at 06:56
  • Well, I found thread called '.NET SystemEvents' and checked sources - it is essentially WndProc thread servicing windows messages. Second thread is assumably GC and my executing Main thread. Checking native threads/stacks also didn't show anything containing waiting single next timer. If I missed something - I'm sorry, I'm not very skilled in low-level native debugging. Could you point place in SSCLI where creating & logic of this thread locates? – Ivan Danilov Jun 14 '11 at 07:48
  • That's not it. Why don't you ask a question about it? Post a link to it and I'll answer it with the amount of detail that doesn't fit in a comment. – Hans Passant Jun 14 '11 at 12:40
  • Good idea :) You're welcome: http://stackoverflow.com/questions/6343733/is-clr-internally-spawns-a-thread-to-respond-to-timer-events – Ivan Danilov Jun 14 '11 at 13:02
  • It is going to take a fair amount of work to turn that into a real question. Maybe if I can find some time later today. – Hans Passant Jun 14 '11 at 14:34
  • @Hans: I've just answered my own question if you're interested. Comments/corrections are welcome. And thanks for your insistence :) – Ivan Danilov Jun 16 '11 at 01:29
3

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?

Community
  • 1
  • 1
lunixbochs
  • 21,757
  • 2
  • 39
  • 47
  • 2
    Also see [Comparing the Timer Classes in the .NET Framework Class Library](http://msdn.microsoft.com/en-us/magazine/cc164015.aspx#S2) – The Scrum Meister Jun 14 '11 at 05:48
1

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.

Sven
  • 21,903
  • 4
  • 56
  • 63