Timers

Timers are lightweight objects that enable you to specify a delegate to be called at a specified time. A thread in the thread pool performs the callback.

Using the Timer class is straightforward. You simply create a Timer, passing to the constructor a TimerCallback delegate that represents the callback method, an object that represents state that will be passed to the callback each time it is invoked, an initial invocation time, and a time that represents the period between callback invocations. To cancel a timer, call the Dispose method.

Note Note:

If you need to access user interface (UI) elements from code that is executed by a thread from the thread pool, use the System.Windows.Threading.Dispatcher class to perform that access on the UI thread.

The following example demonstrates the features of the Timer class. This example creates a timer, uses the Change method to change its interval, and then uses the Dispose method to destroy it. The changes to the timer occur when the mouse is clicked.

The example displays its output in a TextBlock on the UI thread. To access the TextBlock from the callback thread, the example uses the Dispatcher property to obtain a Dispatcher object for the TextBlock, and then uses the Dispatcher.BeginInvoke method to make the cross-thread call.


using System;
using System.Threading;

// The following Imports are not required for the timer. They merely simplify 
// the code.
using System.Windows.Controls;
using System.Windows.Input;

// The Example class holds a reference to the timer, and contains the 
// event handler for the MouseLeftButtonUp events that control the demo.
//
public class Example
{
   // The static Demo method sets the starting message and creates an 
   // instance of Example, which hooks up the handler for the MouseLeftButtonUp
   // event.
   public static void Demo(TextBlock outputBlock)
   {
      outputBlock.Text += "Click to create the timer.\n";
      Example dummy = new Example(outputBlock);
   }


   // Instance data for the demo.
   private int phase = 0;
   private Timer t;

   public Example(TextBlock outputBlock)
   {
      // Hook up the mouse event when a new Example object is created. Note
      // that this keeps garbage collection from reclaiming the Example 
      // object.
      outputBlock.MouseLeftButtonUp += new MouseButtonEventHandler(this.MouseUp);
   }

   private void MouseUp(object sender, MouseButtonEventArgs e)
   {
      TextBlock outputBlock = (TextBlock) sender;

      if (phase==0)
      {
         // On the first click, create the timer.
         outputBlock.Text += "\nCreating the timer at " + 
               DateTime.Now.ToString("h:mm:ss.fff") + 
               ", to start in 1 second with a half-second interval.\n" +
               "Click to change the interval from 1/2 second to 1 second.\n\n";

         // Create a timer that invokes the callback method after one second 
         // (1000 milliseconds) and every 1/2 second thereafter. The TextBlock
         // that is used for output is passed as the state object. C# infers the 
         // delegate type, as if you had typed the following:
         //     new TimerCallback(MyTimerCallback)
         // 
         t = new Timer(MyTimerCallback, outputBlock, 1000, 500);

      }
      else if (phase==1)
      {
         outputBlock.Text += "\nChanging the interval to one second.\n" +
                             "Click to destroy the timer.\n\n";
         t.Change(0, 1000);
      }
      else
      {
         // On the last click, destroy the timer and shut down the demo.
         outputBlock.Text += "\nDestroying the timer.\n" + 
                             "Refresh the page to run the demo again.";
         outputBlock.MouseLeftButtonUp -= new MouseButtonEventHandler(this.MouseUp);

         t.Dispose();
      }

      phase += 1;
   }


   // The static callback method is invoked on a ThreadPool thread by the Timer. 
   // The state object is passed to the callback method on each invocation. In this
   // example, the state object is the TextBlock that displays output. In order to
   // update the TextBlock object, which is on the UI thread, you must make the  
   // cross-thread call by using the Dispatcher object that is associated with the 
   // TextBlock.
   private static void MyTimerCallback(object state)
   {
      TextBlock outputBlock = (TextBlock) state;
      string msg = DateTime.Now.ToString("h:mm:ss.fff") + " MyTimerCallback was called.\n";

      outputBlock.Dispatcher.BeginInvoke(delegate () { outputBlock.Text += msg; });
   }
}

/* This example produces output similar to the following:

Click to create the timer.

Creating the timer at 3:40:17.712, to start in 1 second with a half-second interval.
Click to change the interval from 1/2 second to 1 second.

3:40:18.820 MyTimerCallback was called.
3:40:19.335 MyTimerCallback was called.
3:40:19.849 MyTimerCallback was called.

Changing the interval to one second.
Click to destroy the timer.

3:40:20.317 MyTimerCallback was called.
3:40:21.331 MyTimerCallback was called.

Destroying the timer.
Refresh the page to run the demo again.
 */


Community Additions

ADD
Show: