Timers

There are various different timers available in .NET, each of which basically calls a delegate after a certain amount of time has passed. This section is a very brief guide to the differences between them. See the resources section for more in depth links. All the timers implement IDisposable, so make sure you dispose of them when you're not using them any more.

System.Windows.Forms.Timer

This is (obviously) a forms-based timer. After creating it, you can set the interval which elapses between ticks (using the Interval property) and hook up a delegate to its Tick event. Calling Start and Stop methods (which effectively just change the value of the Enabled property) do the obvious things. While the timer is running, it generates ticks and fires the Tick event each time. Note, however, that because it runs entirely on the UI thread, if you have long-running UI operations, you may "miss" ticks if more than one would normally occur in the time taken by the long-running operation. Effectively, it keeps track of when its next tick is due, and when it next gets a chance to run, if the time is up, it fires the event. Personally, I find this the least useful of the timer classes.

System.Timers.Timer

This is a somewhat more powerful timer. Instead of a Tick event, it has the Elapsed event. As before, there are Start and Stop methods which are similar to changing the Enabled property. Changing the Interval or Enabled properties effectively reset the timer. (In other words, if the interval were set to two seconds, and every second you disabled and then re-enabled the timer, the event would never be fired.) The AutoReset property determines whether or not the timer should fire the event once and then stop, or keep going in a fire event / wait cycle.

By default, the event is fire on a thread pool thread. However, if you wish it to be fired on a particular thread, you can use the SynchronizingObject property which makes it invoke the event however the synchronizing object wishes it to. For instance, setting the synchronizing object to a UI control makes the event fire on that control's UI thread. Unlike the previous timer, the events are effectively queued - the timer doesn't wait for one event to have completed before starting to wait again and then firing off the next event.

System.Threading.Timer

This is the timer class I usually prefer, due to its simplicity. When constructing it, you need to pass in a TimerCallback delegate, a state object which is passed to the delegate when the timer fires, a "due" time and an interval. The timer will first fire after the due time has elapsed, and thereafter it will fire after each interval. Either value may be Timeout.Infinite - if the due time is infinite, the timer will never fire; if the interval is infinite, the timer will fire once (after the due time) and then it won't fire again. You can change the due time and the interval at any point using the Change method. (For instance, I sometimes find it useful to leave the interval as infinite, but every time the timer fires, call Change with a new due time.)

There's nothing fancy about this timer: the timer always fires on a thread pool thread. If you need to use it to update the UI, you need to use the techniques talked about in the Windows Forms section. You don't start and stop it - if you don't want it to fire, just change the due time to be infinite.

Examples

Timers are simple enough that for the most part they don't really need examples, in my view. Just for kicks, here's a sample of System.Threading.Timer. If you really need other examples, please mail me and let me know what exactly you're after. Note that the article in the resources section has some sample code too.

using System;
using System.Threading;

public class Test
{
    static void Main()
    {
        Console.WriteLine ("Started at {0:HH:mm:ss.fff}", DateTime.Now);
        // Start in three seconds, then fire every one second
        using (Timer timer = new Timer(new TimerCallback(Tick), null, 3000, 1000))
        {
        
            // Wait for 10 seconds
            Thread.Sleep(10000);
            
            // Then go slow for another 10 seconds
            timer.Change (0, 2000);
            Thread.Sleep(10000);
        }
        
        // The timer will now have been disposed automatically due to the using
        // statement, so there won't be any other threads running, and we'll quit.
    }    
    
    static void Tick(object state)
    {
        Console.WriteLine ("Ticked at {0:HH:mm:ss.fff}", DateTime.Now);
    }
}

And here are the results of one run of that test:

Started at 15:32:07.473
Ticked at 15:32:10.520
Ticked at 15:32:11.520
Ticked at 15:32:12.520
Ticked at 15:32:13.520
Ticked at 15:32:14.520
Ticked at 15:32:15.520
Ticked at 15:32:16.520
Ticked at 15:32:17.520
Ticked at 15:32:17.536
Ticked at 15:32:19.552
Ticked at 15:32:21.552
Ticked at 15:32:23.552
Ticked at 15:32:25.552
Ticked at 15:32:27.552

Note the very small gap between the ticks at 15:32:17 - this was where Change was called with a due time of zero, which means "fire the delegate now".


Next page: Shutting Down Worker Threads Gracefully
Previous page: The Thread Pool and Asynchronous Methods


Back to the main C# page.