Setting up windows service with Topshelf and HangFire


Problem: Debugging and maintenance of a windows service is a tedious task. Below are few issues which we face generally while working with windows services.

  1. To debug the windows service locally, we need to install the service locally and need to explicitly launch the debugger (“System.Diagnostics.Debugger.Launch(); “) in the OnStart() method of the windows service.
  2. For some reason if windows service got crashed or stopped, then we need to manually start the service, or deploy the service again.
  3. In some scenarios even windows updates can affect the job scheduler. So in those cases the jobs won’t be running as scheduled.

Solution:

In this blog post I am going to walk you through how we can simply the development of the windows services and also to overcome the above mentioned issues with sample code.

I will be using Topshelf and HangFire packages to develop and maintain windows service.

Topshelf gives us the flexibility to debug windows service locally without deploying and invoking the debugger explicitly. And also it provides a flexibility to host windows service as Azure Cloud Service.

HangFire helps us to manage, process our services as jobs. It supports all kinds of jobs like short-running and long-running, CPU intensive and I/O intensive, one shot and recurrent.

In this blog I am going to discuss about recurring jobs, so I’ll be using CRON expressions to schedule the jobs.

I have created a console application which is used to integrate Topshelf, HangFire and windows service.

  1. Create a console application and install Owin, Topshelf, HangFire packages from nuget.
  2. Edit Program.cs file to construct the service using Topshelf.

3. Create a class BootStrap.cs. In this we will configure our HangFire to be hosted on Owin. (StartOptions has to be imported from “Microsoft.Owin.Hosting” and not from “Topshelf.Options”).

4. Create a class Startup.cs, where we will configure our HangFire database and the HangFire Dashboard.

5. Create a class HangFireService.cs, where we will add, schedule and remove the jobs from the HangFire job manager.

6. Based on the HangFire configuration, jobs configured in the HangFire will be restarted periodically. Whenever the jobs get restarted we need to perform in the following sequence.

Stop any running jobs.
Get all jobs that are to be added to HangFire Scheduler.
Run the jobs based on the schedule specified in the CRON expression.

7. To stop the executing jobs, we need to get all the recurring jobs from the HangFire database, and remove them from the JobManager.

8. Provide all the job configuration details like — Job Id, Type name, CRON expression, job is enabled or not. Add all these jobs to JobManager.

9. Schedule all the jobs which are added to the JobManager.

Method Start() in the below snippet (ln. 20) is defined in the class which is specified in the TypeName of the job configuration details. This method is mainly responsible for executing the actual windows service business logic.

Once the job is scheduled, the job will run for every xyz minutes depending on the CRON expression of that job.

If you want to debug the service at the time of development, set the console app as start up project and run the application. If you want to run the application in release mode, run the .exe file from the bin folder. In this way we can simplify the development of windows services and also the installation, start/ stop of the service.

Here is the source code for the sample.

Utkarsh Shigihalli, thanks for your inputs.