Recipe 15.11 Configuring a Timer
Problem
You have one of the following
timer configuration needs:
You want to use a timer to call a timer callback method at a fixed
time after the timer object has been created. Once this callback
method has been called the first time, you want to call this same
callback method at a specified interval (this interval might be
different from the time interval between the creation of the timer
and the first time the timer callback method is called). You want to use a timer to call a timer callback method immediately
upon creation of the System.Threading.Timer
object, after which the callback method is called at a specified
interval. You want to use a timer to call a timer callback method one time only. You have been using a System.Threading.Timer
object and need to change the intervals at which its timer callback
method is called.
Solution
To fire a
System.Threading.Timer after an initial delay, and
then at a specified period after that, use the
System.Threading.Timer constructor to set up
different times for the initial and following callbacks:
using System;
using System.Threading;
public class TestTimers
{
public static int count = 0;
public static Timer timerRef = null;
public static void Main( )
{
TimerCallback callback = new TimerCallback(TimerMethod);
// Create a timer that waits one half second, then invokes
// the callback every second thereafter.
Timer timer = new Timer(callback, null,500, 1000);
// store a reference to this timer so the callback can use it
timerRef = timer;
// The main thread does nothing until the timer is disposed.
while(timerRef != null)
Thread.Sleep(0);
Console.WriteLine("Timer example done.");
}
static void TimerMethod(Object state)
{
count++;
if(count == 5)
{
timerRef.Dispose( );
timerRef = null;
}
}
}
The previous method showed how to fire the callback after 500
milliseconds. To fire the initial callback immediately, change the
value to zero:
// Create a timer that doesn't wait, then invokes
// the callback every second thereafter.
Timer timer = new Timer(callback, null,0, 1000);
To have the timer call the callback only once, change the constructor
to pass Timeout.Infinite for the callback
interval. You also have to change the current scheme that waits for
five callbacks before disposing of the timer to do it the first time.
If you didn't do this, the program would hang since
the Main function is still waiting for the timer
to have Dispose called, but the fifth callback
will never trigger the Dispose call:
// Create a timer that waits for half a second, then is disposed
Timer timer = new Timer(callback, null,500, Timeout.Infinite);
// Also change this...to
static void TimerMethod(Object state)
{
timerRef.Dispose( );
timerRef = null;
}
To change the interval of a running
System.Threading.Timer, call the
Change method specifying the delay before the next
callback and the new callback interval, like this:
static void TimerMethod(Object state)
{
count++;
if(count == 5)
{
timerRef.Change(1000,2000);
}
if(count == 10)
{
timerRef.Dispose( );
timerRef = null;
}
}
This code now checks for the fifth callback and changes the interval
from one second to two seconds. The sixth callback will happen one
second after, and then callbacks through ten will happen two seconds
apart.
Discussion
One item to be aware of when using
System.Threading.Timers and
TimerCallbacks is
that they are serviced from the ThreadPool. This
means that if you have other work being farmed out to the
ThreadPool in your application, it could be
contending with the Timer callbacks for an
available worker thread. The basic timer is enough to serve the
earlier scenarios, but if you are doing UI work and want to use
timers, you should investigate the
System.Windows.Forms.Timer class. If you are doing
server work, you might also want to look at
System.Timers.Timer as well. Both of these classes
add events for when the timers are disposed and when the timer
"ticks"; they also add properties
that expose the settings.
See Also
See the "System.Threading.Timer
Class," "TimerCallback
Delegate,"
"System.Windows.Forms.Timer Class,"
and "System.Timers.Timer" topics in
the MSDN documentation.
|