Creating a .NET Windows Service—The Timer Approach

Microsoft .NET Framework, ASP.NET, Visual C# (CSharp, C Sharp, C-Sharp) Developer Training, Visual Studio


Jump to: navigation, search
CSharp-Online.NET:Articles
.NET Articles

Create .NET Windows Service

© 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.


Previous_Page_.gif Next_Page_.gif

Personal tools