C# – background worker with windows service

cwindows-services

I'm creating a windows service in Visual Studio 2010 with C# and I have few methods like Add, Multiply and others, which I'm putting in the onStart method. Now, I want these methods to run after every five minutes. So how would a background worker process help me in this?

protected override void OnStart(string[] args)
{
    add(); // yes, it doesn't have parameters      
}

Best Answer

The timer is the right way to go. I have a slightly enhanced version that takes care of the shutdown of the timer in the OnStop method.

in your program.cs, I would do the following to make debugging easier:

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;

namespace SampleWinSvc
{
  static class Program
  {
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main()
    {
#if (!DEBUG)
      ServiceBase[] ServicesToRun;
      ServicesToRun = new ServiceBase[] { new Service1() };
      ServiceBase.Run(ServicesToRun);
#else
      //Debug code: this allows the process to run 
      // as a non-service. It will kick off the
      // service start point, and then run the 
      // sleep loop below.
      Service1 service = new Service1();
      service.Start();
      // Break execution and set done to true to run Stop()
      bool done = false;
      while (!done)
        Thread.Sleep(10000);
      service.Stop();
#endif
    }
  }
}

Then, in your Service1.cs code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Timers;
using System.Text;

namespace SampleWinSvc
{
    public partial class Service1 : ServiceBase
    {
        /// <summary>
        /// This timer willl run the process at the interval specified (currently 10 seconds) once enabled
        /// </summary>
        Timer timer = new Timer(10000);

        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            Start();
        }

        public void Start()
        {
            // point the timer elapsed to the handler
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            // turn on the timer
            timer.Enabled = true;
        }

        /// <summary>
        /// This is called when the service is being stopped. 
            /// You need to wrap up pretty quickly or ask for an extension.
        /// </summary>
        protected override void OnStop()
        {
            timer.Enabled = false;
        }

            /// <summary>
            /// Runs each time the timer has elapsed. 
            /// Remember that if the OnStop turns off the timer, 
            /// that does not guarantee that your process has completed. 
            /// If the process is long and iterative, 
            /// you may want to add in a check inside it 
            /// to see if timer.Enabled has been set to false, or 
            /// provide some other way to check so that 
            /// the process will stop what it is doing.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
        void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            MyFunction();
        }

        private int secondsElapsed = 0;
        void MyFunction()
        {
            secondsElapsed += 10;
        }
    }
}

By setting the #DEBUG var in your compile options you allow yourself to run the code as a program and then when you are ready to test your shutdown logic, simply break all and set done to true. I have been using this method for years with much success.

As commented in the code, if you are doing anything lengthy in your timer event, then you may want to monitor it from the OnStop to make sure it has enough time if shutdown in the middle of things.