Do C# Timers Elapse on a Separate Thread

Do C# Timers elapse on a separate thread?

For System.Timers.Timer:

See Brian Gideon's answer below

For System.Threading.Timer:

MSDN Documentation on Timers states:

The System.Threading.Timer class makes
callbacks on a ThreadPool thread
and
does not use the event model at all.

So indeed the timer elapses on a different thread.

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

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.

Timer runs in different thread than the one that created it

Yeah, you're just dealing with two separate Timer classes. System.Windows.Forms.Timer fires its Tick event on the main thread and System.Timers.Timer fires its Elapsed event on a background thread. The advantage of System.Windows.Forms.Timer is that it hides the threading; the advantage of System.Timers.Timer is that it doesn't require a message pump to work.

You ask, "How do I reliably create timers that will execute in the thread where I create them?" Well, this is easy when you have a Windows Forms GUI and are starting the Timer on the UI thread: just use System.Windows.Forms.Timer. If you don't have a message pump to take advantage of, you have to use a System.Timers.Timer and basically the only way to run something on the main thread when the timer fires its Elapsed event is to recreate something like a message loop in your main thread--have it sit, maybe waiting for a Monitor.Pulse or some other kind of notification from the timer thread. But this means your main thread won't be getting anything useful done in the meantime...

Do System.Timers.Timer run in independent Threads?

According to the MSDN, on System.Timers.Timer when the Elapsed event fires it is called on a thread in the system thread-pool:

If the SynchronizingObject property is Nothing, the Elapsed event is raised on a ThreadPool thread. If processing of the Elapsed event lasts longer than Interval, the event might be raised again on another ThreadPool thread. In this situation, the event handler should be reentrant.

Since the default value of SynchronizingObject is null, then all your elapsed events would be handled on the thread pool. So, it depends how full the thread pool is, if there are free threads, then each elapsed event can most likely run concurrently on separate threads. If for some reason, though, the system thread-pool is already fully in use, it's possible the elapsed events could be serialized as they are scheduled.

The main point is: "it depends." That is, they will be allowed to run in parallel as long as there are free threads in the pool.

Reference: MSDN on System.Timers.Timer

start a timer from different thread in c#


You could try to start the timer this way:

Add in form constructor this:

System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Set the Interval to 1 second.
aTimer.Interval = 1000;

Add this method to Form1:

 private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
//do something with the timer
}

On button click event add this:

aTimer.Enabled = true;

This timer is already threaded so no need to start a new thread.

Can System.Timers.Timer elapsed event if previous event still working?

System.Timers.Timer(Multi Threaded Timer) is multithreaded timer. that means it executes it elapse event on multiple thread and that means it don't wait for previous elapse event.

if you want to wait for previous elapse event to complete that you can use System.Windows.Timer (Single Threaded Timer) - this is single threaded timer will execute event on single thread only(UI thread) which created timer.

You can read more about this here : Timers written by Joe Albahari

More timers at same time in different threads

Of course it is possible to run more separate WorkerThreads. Each one will have it's own timer. There shouldn't be a problem.

The variable bool elapsed will be set to true by the first Thread that finishes its job, and it will stay true until some other process sets it to false. If you are unlucky some thread might even not start its job because the first on has set your elapsed to true

EDIT:

it seems that your thread job is encapsulated.
So you could actually also just use a stopwatch, if you don't need to access global variables from within the thread

private void WorkerThreadFunction()
{
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
watch.Start();

while(watch.ElapsedMilliseconds < 60000)
{
// Do something...
Thread.Sleep(50);
}

watch.Stop();
}

Which thread does my timer elapsed method get called on?

The thread is one out of the threadpool. There is no way to prodict which thread will be associated with the elapsed method.

Details: http://msdn.microsoft.com/en-us/library/system.timers.timer.elapsed.aspx

(And it should not matter, from a designs perspective)

Edit: Actually there is a method to define which thread is used; You can used the SynchronizingObject property of the timer:

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.

When the Elapsed event is handled by a visual Windows Forms component,
such as a button, accessing the component through the system-thread
pool might result in an exception or just might not work. Avoid this
effect by setting SynchronizingObject to a Windows Forms component,
which causes the method that handles the Elapsed event to be called on
the same thread that the component was created on.

See: http://msdn.microsoft.com/en-us/library/system.timers.timer.synchronizingobject.aspx



Related Topics



Leave a reply



Submit