4.3 Execute a Method Using a Timer


Problem

You need to execute a method in a separate thread either periodically or at a specific time.

Solution

Declare a method that returns void and takes a single object argument. Create a System.Threading.TimerCallback delegate instance that references the method. Create a System.Threading.Timer object and pass it the TimerCallback delegate instance along with a state object that the timer will pass to your method when the timer expires. The runtime will wait until the timer expires and then call your method using a thread from the thread pool.

Discussion

It's often useful to execute a method at a particular time or at regular intervals. For example, you might need to back up data at 1:00 A.M. every day or to clean a data cache every 20 minutes. The Timer class makes the timed execution of methods straightforward, allowing you to execute a method referenced by a TimerCallback delegate at specified intervals. The referenced method executes in the context of a thread from the thread pool.

When you create a Timer object, you specify two time intervals. The first value specifies the millisecond delay until the Timer first executes your method. Specify 0 to execute the method immediately, and System.Threading.Timeout.Infinite to create the Timer in an unstarted state. The second value specifies the interval after which the Timer will repeatedly call your method following the initial execution. If you specify a value of 0 or Timeout.Infinite , the Timer will execute the method only once (as long as the initial delay is not Timeout.Infinite ). The time intervals can be specified as int , long , uint , or System.TimeSpan values.

Once you have created a Timer object, you can modify the intervals used by the timer using the Change method, but you can't change the method that is called. When you have finished with a Timer you should call its Dispose method to free system resources held by the timer. Disposing of the Timer cancels any method that is scheduled for execution.

The TimerExample class shown here demonstrates the use of a Timer to call a method named TimerHandler . Initially, the Timer is configured to call TimerHandler after two seconds and then at one-second intervals. The example allows you to enter a new millisecond interval in the console, which is applied using the Timer.Change method.

 using System; using System.Threading; public class TimerExample {     // The method that is executed when the timer expires. Displays     // a message to the console.     private static void TimerHandler(object state) {         Console.WriteLine("{0} : {1}",             DateTime.Now.ToString("HH:mm:ss.ffff"), state);     }     public static void Main() {         // Create a new TimerCallback delegate instance that          // references the static TimerHandler method. TimerHandler          // will be called when the timer expires.         TimerCallback handler = new TimerCallback(TimerHandler);         // Create the state object that is passed to the TimerHandler         // method when it is triggered. In this case a message to display.         string state = "Timer expired.";         Console.WriteLine("{0} : Creating Timer.",             DateTime.Now.ToString("HH:mm:ss.ffff"));         // Create a Timer that fires first after 2 seconds and then every         // second.         using (Timer timer = new Timer(handler, state, 2000, 1000)) {             int period;             // Read the new timer interval from the console until the             // user enters 0 (zero). Invalid values use a default value             // of 0, which will stop the example.             do {                 try {                     period = Int32.Parse(Console.ReadLine());                 } catch {                     period = 0;                 }                 // Change the timer to fire using the new interval starting                 // immediately.                 if (period > 0) timer.Change(0, period);             } while (period > 0);         }         // Wait to continue.         Console.WriteLine("Main method complete. Press Enter.");         Console.ReadLine();     } } 

Although primarily used for calling methods at regular intervals, the Timer also provides the flexibility to call a method at a specific time. You must calculate the difference between the current time and the desired execution time as demonstrated in the RunAt method shown here. (The RunAt method is a member of the RunAtExample class in the sample code for this chapter.)

 public static void RunAt(DateTime execTime) {     // Calculate the difference between the specified execution      // time and the current time.     TimeSpan waitTime = execTime - DateTime.Now;     if (waitTime < new TimeSpan(0)) waitTime = new TimeSpan(0);     // Create a new TimerCallback delegate instance that      // references the static TimerHandler method. TimerHandler      // will be called when the timer expires.     TimerCallback handler = new TimerCallback(TimerHandler);     // Create a Timer that fires once at the specified time. Specify     // an interval of -1 to stop the timer executing the method     // repeatedly.     new Timer(handler, null, waitTime, new TimeSpan(-1)); } 



C# Programmer[ap]s Cookbook
C# Programmer[ap]s Cookbook
ISBN: 735619301
EAN: N/A
Year: 2006
Pages: 266

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net