[c#] Do C# Timers elapse on a separate thread?

Does a System.Timers.Timer elapse on a separate thread than the thread that created it?

Lets say I have a class with a timer that fires every 5 seconds. When the timer fires, in the elapsed method, some object is modified. Lets say it takes a long time to modify this object, like 10 seconds. Is it possible that I will run into thread collisions in this scenario?

This question is related to c# multithreading timer

The answer is


For System.Timers.Timer, on separate thread, if SynchronizingObject is not set.

    static System.Timers.Timer DummyTimer = null;

    static void Main(string[] args)
    {
        try
        {

            Console.WriteLine("Main Thread Id: " + System.Threading.Thread.CurrentThread.ManagedThreadId);

            DummyTimer = new System.Timers.Timer(1000 * 5); // 5 sec interval
            DummyTimer.Enabled = true;
            DummyTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnDummyTimerFired);
            DummyTimer.AutoReset = true;

            DummyTimer.Start();

            Console.WriteLine("Hit any key to exit");
            Console.ReadLine();
        }
        catch (Exception Ex)
        {
            Console.WriteLine(Ex.Message);
        }

        return;
    }

    static void OnDummyTimerFired(object Sender, System.Timers.ElapsedEventArgs e)
    {
        Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
        return;
    }

Output you'd see if DummyTimer fired on 5 seconds interval:

Main Thread Id: 9
   12
   12
   12
   12
   12
   ... 

So, as seen, OnDummyTimerFired is executed on Workers thread.

No, further complication - If you reduce interval to say 10 ms,

Main Thread Id: 9
   11
   13
   12
   22
   17
   ... 

This is because if prev execution of OnDummyTimerFired isn't done when next tick is fired, then .NET would create a new thread to do this job.

Complicating things further, "The System.Timers.Timer class provides an easy way to deal with this dilemma—it exposes a public SynchronizingObject property. Setting this property to an instance of a Windows Form (or a control on a Windows Form) will ensure that the code in your Elapsed event handler runs on the same thread on which the SynchronizingObject was instantiated."

http://msdn.microsoft.com/en-us/magazine/cc164015.aspx#S2


If the elapsed event takes longer then the interval, it will create another thread to raise the elapsed event. But there is a workaround for this

static void timer_Elapsed(object sender, ElapsedEventArgs e)    
{     
   try
   {
      timer.Stop(); 
      Thread.Sleep(2000);        
      Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);    
   }
   finally
   {
     timer.Start();
   }
}

It depends. The System.Timers.Timer has two modes of operation.

If SynchronizingObject is set to an ISynchronizeInvoke instance then the Elapsed event will execute on the thread hosting the synchronizing object. Usually these ISynchronizeInvoke instances are none other than plain old Control and Form instances that we are all familiar with. So in that case the Elapsed event is invoked on the UI thread and it behaves similar to the System.Windows.Forms.Timer. Otherwise, it really depends on the specific ISynchronizeInvoke instance that was used.

If SynchronizingObject is null then the Elapsed event is invoked on a ThreadPool thread and it behaves similar to the System.Threading.Timer. In fact, it actually uses a System.Threading.Timer behind the scenes and does the marshaling operation after it receives the timer callback if needed.


Each elapsed event will fire in the same thread unless a previous Elapsed is still running.

So it handles the collision for you

try putting this in a console

static void Main(string[] args)
{
    Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
    var timer = new Timer(1000);
    timer.Elapsed += timer_Elapsed;
    timer.Start();
    Console.ReadLine();
}

static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    Thread.Sleep(2000);
    Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
}

you will get something like this

10
6
12
6
12

where 10 is the calling thread and 6 and 12 are firing from the bg elapsed event. If you remove the Thread.Sleep(2000); you will get something like this

10
6
6
6
6

Since there are no collisions.

But this still leaves u with a problem. if u are firing the event every 5 seconds and it takes 10 seconds to edit u need some locking to skip some edits.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to multithreading

How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Waiting until the task finishes What is the difference between Task.Run() and Task.Factory.StartNew() Why is setState in reactjs Async instead of Sync? What exactly is std::atomic? Calling async method on button click WAITING at sun.misc.Unsafe.park(Native Method) How to use background thread in swift? What is the use of static synchronized method in java? Locking pattern for proper use of .NET MemoryCache

Examples related to timer

Flutter Countdown Timer How to do a timer in Angular 5 Create a simple 10 second countdown Python loop to run for certain amount of seconds Error 1053 the service did not respond to the start or control request in a timely fashion Wait some seconds without blocking UI execution The simplest possible JavaScript countdown timer? How can I perform a short delay in C# without using sleep? How to add a "sleep" or "wait" to my Lua Script? How to use timer in C?