Using Timers in a Windows Service

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Welcome to the next installment of the .NET Nuts & Bolts column. In one of the prior columns, “Creating a Windows Service in .NET,” we looked at the basics of creating a Windows Service. As a result of that article, I received a number of requests about how to create a service that takes an action on a scheduled interval. In this column, we’ll get more in depth with Windows Services and explore how to use timers within them. It will involve using classes in the System.ServiceProcess.ServiceBase and System.Timers namespaces, among others.

Windows Service Recap

A Windows Service is a long-running application without a user interface or any visual output. They are ideal for server environments where an application needs to continue to run regardless of whether a user is logged into the console or not. Microsoft server products, such as SQL Server and Exchange, are examples of Windows Service applications. For more basic information on Windows Services, refer to the prior .NET Nuts & Bolts column titled “Creating a Windows Service in .NET.”

What Is a Timer?

A timer is an object that can be used in your applications to cause an event to occur on a specified interval. There are three timer controls available within the Microsoft .NET Framework. Each one has it specific nuances. The three types of timers are as follows:

  • System.Windows.Forms.Timer—is designed for use in a single threaded Windows Forms based application. This is the same timer design as what has been available since early versions of Visual Basic. A common mistake is attempting to use this timer in a Windows Service application.
  • System.Timers.Timer—is an updated version of the Windows Forms timer that has been optimized to run in a server environment where a user interface does not exist. This timer is ideal for use in Windows Services.
  • System.Threading.Timer—is designed for use with ThreadPools. It uses callback methods rather than events and therefore does not rely on the operating system to support timers. We won’t cover this timer as a part of this article.

Controlling a Timer

Each of the timers exposes some basic properties and methods that allow you to control its behavior. The Windows.Forms.Timer and Timers.Timer classes expose the same items:

  • Enabled—property indicating whether or not the timer is enabled and should be raising the event.
  • Interval—property allowing you to set the number of milliseconds between events.
  • Start—method allowing you to start the timer.
  • Stop—method allowing you to stop the timer.

The System.Threading.Timer object has different properties and methods for controlling its behavior. We’re not going to cover the use of this timer here, so we’ll skip the particulars.

Using a System.Timers.Timer Sample Code

The following sample code briefly demonstrates the programmatic setup of a timer in the System.Timers namespace. This example uses a Windows console application for simplicity in being able to see the outcome without requiring a lot of setup.

using System;

namespace ConsoleTimer
{
   /// <summary>
   /// Sample class for testing a server based timer.
   /// </summary>
   class Class1
   {
      System.Timers.Timer testTimer = new System.Timers.Timer();

      /// <summary>
      /// The main entry point for the application.
      /// </summary>
      [STAThread]
      static void Main(string[] args)
      {
         Class1 test = new Class1();
         test.testTimer.Enabled = true;
         test.testTimer.Interval = 5000;    // Execute timer every
                                            // five seconds
         test.testTimer.Elapsed += new
            System.Timers.ElapsedEventHandler(test.testTimer_Elapsed);

         // Sit and wait so we can see some output
         Console.ReadLine();
      }

      private void testTimer_Elapsed(object sender,
         System.Timers.ElapsedEventArgs e)
      {
         System.Console.WriteLine("myTimer event occurred");
      }
   }
}

Using a System.Timers.Timer in a Windows Service

Now that we have seen a simple example of using a timer, we’ll get more complex and apply them to a Windows Service. The example in the prior column showed the creation and use of a single timer. This time around, we’ll spin up a number of threads and execute multiple timers. This will give us the opportunity to show how to set configurations in threads as well. The first thing we’ll need to do is create our item that will run as a thread. Then, we’ll create the Windows Service to create the threads. Finally, we’ll add an installer to handle the installation of the Windows Service.

TimedItem Sample Code

The following sample code contains an object with a single timer. It simply starts and stops the timer and responds to the timer’s event when appropriate. Because parameters cannot be passed to threads, we create a class like this and set the properties equal to the values we would want to pass as parameters to the method running as a thread. Each time the event fires for the item, an entry will be written to the Application log.

using System;

namespace CodeGuru.TimerService
{
   /// <summary>
   /// Demonstrate the use of a timer.
   /// </summary>
   public class TimedItem
   {
      private System.Diagnostics.EventLog _AppEventLog;
      private System.Timers.Timer _Timer;

      private int _Interval = 30000;
      public int Interval
      {
         get { return this._Interval; }
         set { this._Interval = value; }
      }

      private string _Name = "";
      public string Name
      {
         get { return this._Name; }
         set { this._Name = value; }
      }

      /// <summary>
      /// Constructor
      /// </summary>
      public TimedItem(System.Diagnostics.EventLog AppEventLog)
      {
         this._Timer = new System.Timers.Timer();
         this._Timer.Elapsed += new
         System.Timers.ElapsedEventHandler(_Timer_Elapsed);
         this._Timer.Enabled = false;
         this._Timer.Interval = this.Interval;
         this._AppEventLog = AppEventLog;
      }

      /// <summary>
      /// Start the timer.
      /// </summary>
      public void StartTimer()
      {
         this._Timer.Enabled = true;
      }

      /// <summary>
      /// Stop the timer.
      /// </summary>
      public void StopTimer()
      {
         this._Timer.Enabled = false;
      }


      /*
       * Respond to the _Timer elapsed event.
       */
      private void _Timer_Elapsed(object sender,
         System.Timers.ElapsedEventArgs e)
      {
         this._AppEventLog.WriteEntry("Time elapsed for " + this.Name,
            System.Diagnostics.EventLogEntryType.Information);
      }
   }
}

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read