
Execute Tasks Periodically
by Alberto Falossi
November 2002 Issue
Technology Toolbox: VB.NET, C#
Level: Intermediate
Applications often need to execute some tasks periodically. For example, a server application might need to back up its data every hour. You must use a timer to enable this feature. A timer lets you delay, and repeat regularly, execution of a routine. The .NET Framework provides three timers: System.Timers.Timer, System.Threading.Timer, and System.Windows.Forms.Timer.
System.Timers.Timer and System.Threading.Timer are the server-based timers, and System.Windows.Forms.Timer is the Windows timer. Each timer exposes substantially the same features as the others, but has a different internal implementation and is optimized for different scenarios. In broad terms, you use Windows timers on WinForms applications, and server-based timers on other types of applications.
System.Timers.Timer is the most complete and accurate .NET timer. This C# code shows you how to use this timer to delay the printing of the sentence "Hello World" for five seconds:
// using System.Timers;
void TestTimer()
{
// create the timer set the event handler
Timer timer = new Timer();
// set the event handler
timer.Elapsed += new
ElapsedEventHandler(OnElapsed);
// set the timer properties
timer.Interval = 5000;
timer.AutoReset = true;
// start the timer
timer.Start();
}
void OnElapsed(Object sender, ElapsedEventArgs e)
{
// on timeout this code is executed
Console.WriteLine("Hello World!");
}
The OnElapsed event handler contains the code to execute when the timeout expires. The Interval property contains the timeout value in milliseconds. The AutoReset property specifies whether to start the timer again after the timeout has elapsed. If you set the AutoReset to false, the elapsed event fires only once; if you set AutoReset to true, the elapsed event fires every five seconds. Start and stop the timer by calling the Start and Stop methods or assigning the Enabled property.
Server-based timers use the thread pool internally, and the event handler runs in a thread taken from the pool. For this reason, conflicts might occur while the event handler is accessing shared variables and modifying controls and forms. See the System.Timers.Timer.SynchronizingObject documentation in the .NET Framework SDK to work around the problem.
System.Timers.Timer is also available as a graphical control to insert in the forms. You'll find the control under the Component tab in the Visual Studio .NET toolbox.
You can consider System.Threading.Timer the lightweight version of System.Timers.Timer. The former has fewer members than the latter and uses callbacks instead of events, and you can't insert it graphically into a WinForms form. Here's the code for printing "Hello World" every five seconds, revisited for the System.Threading.Timer:
// using System.Threading;
void TestTimer2()
{
// create and start the timer
Timer timer = new Timer(new
TimerCallback(CallbackProc), null,
5000, 5000);
}
void CallbackProc(object obj)
{
// on timeout this code is executed
Console.WriteLine("Hello World!");
}
System.Threading.Timer doesn't expose the methods and properties of System.Timers.Timer. To change its behavior, you must use different combinations of values for the parameters of the timer's constructor and Change method. See the System.Threading.Timer's constructor help on the .NET Framework SDK for details. Here are some practical examples:
// execute only once after 1 sec.
Timer timer = new Timer(new
TimerCallback(CallbackProc), null, 1000,
Timeout.Infinite);
// execute immediately,
// then repeat every 1 sec.
Timer timer = new Timer(new
TimerCallback(CallbackProc), null, 0,
1000);
// stop the timer
timer.Change(Timeout.Infinite, Timeout.Infinite);
The Windows timer is included in the System.Windows.Forms namespace and is optimized for use in WinForms applications. It's easy to use, but you can't use it in a multithreading environment, and you can't use it in a console application because it requires the presence of a form.
The System.Windows.Forms.Timer control is similar to the VB6 timer control. You put it in a form, set the Interval, and start the countdown by setting the Enabled property to true. On the timeout, the control fires a Tick event:
// Tick event handler for the timer1 control
private void timer1_Tick(object sender,
System.EventArgs e)
{
MessageBox.Show("Hello World!");
}
The Windows timer uses the form message loop, so the notification might be not accurate when a form executes complex computations; it could be delayed by milliseconds. Use a server-based timer instead if you need precise notifications.
About the Author
Alberto Falossi is a .NET trainer and consultant based in Italy. He is the technical editor of Visual Basic & .NET Journal, VSM's Italian licensee, and is a member of the VB-2-The-Max team (). Reach Alberto at .
|