Creating a .NET Windows Service—The Timer Approach
Microsoft .NET Framework, ASP.NET, Visual C# (CSharp, C Sharp, C-Sharp) Developer Training, Visual Studio
| CSharp-Online.NET:Articles |
| .NET Articles |
| © 2005 Pearson Education, Inc. |
The Timer Approach
Of course, it's not very difficult to make the service invoke your worker functions periodically—it just takes a few extra lines of code to use a timer to activate the worker function periodically. The timer approach is the most common method and is probably the simplest to write and understand. You create a timer in the OnStart event and attach your worker function to the timer. Listing 2 demonstrates the timer approach.
Listing 2 OnStart method for the timer approach.
// declare class-level variable for the timer private Timer serviceTimer; ... protected override void OnStart(string[] args) { TimerCallback timerDelegate = new TimerCallback(DoWork); // create timer and attach our method delegate to it serviceTimer = new Timer(timerDelegate, null, 1000, _interval); }
DoWork is the method that contains code to do whatever you need to do periodically, when the timer fires. The code in Listing 3 simply writes to the event log.
Listing 3 Worker method for the timer approach.
private void DoWork(object state) { if (_workStartTime != DateTime.MinValue) { // probably check how much time has elapsed since work // started previously and log any warning EventLog.WriteEntry("Warning! Worker busy since " + _workStartTime.ToLongTimeString(), System.Diagnostics.EventLogEntryType.Warning); } else { // set work start time _workStartTime = DateTime.Now; // Do some work // Note: Exception handling is very important here // if you don't, the error will vanish along with your worker thread try { EventLog.WriteEntry ("Timer Service Tick :" + DateTime.Now.ToString()); } catch (System.Exception ex) { // replace this with some robust logging technique EventLog.WriteEntry("Error! " + ex.Message, System.Diagnostics.EventLogEntryType.Error); } // reset work start time _workStartTime = DateTime.MinValue; } }
At each timer event, we check whether work is going on from a previous event. This is done by setting the _workStartTime variable to DateTime.Now when work starts. The variable is reset to DateTime.MinValue when work is complete. If work is still going on at a subsequent event, we log a warning.
Notice the error handling around the "work." If you don't have exception handling there and an exception occurs, you'll never know that an error happened, and your worker thread will simply die. But the service will keep running normally, unaware that the worker thread has terminated.
A few lines of code accomplished what we wanted. But are there other ways to do what we did above? Definitely. Let's look at two other alternatives, which require slightly more code but are as elegant as the timer approach.
|

