Home » Good Practices » Scheduled jobs made easy – Topshelf and Quartz.NET

Scheduled jobs made easy – Topshelf and Quartz.NET

I often work on applications whose sole task is to execute a script at certain time or day. You may approach it in several ways, eg.: Task Scheduler (Windows), SQL Job (if it is a SQL task) or CRON in Linux. You may also write application, which would run in background and execute a script at certain time. The only question is – do you really want do it?

In this post, I would like to introduce other solution to tasks like this. The combination of two frameworks: Topshelf (Windows host) and Quartz.NET (free-for-business company Task Scheduler).

Topshelf

Topshelf is a framework that makes it easy to launch Windows services written in .NET. Thanks to this, a developer working on a Windows Service can focus solely on building business logic instead of complex configuration service.

Quartz.NET

Quartz.NET is a fully functional framework for creating tasks in time. It is written from scratch in .NET based on a popular framework written in Java – Quartz.

How do they work together?

To connect Topshelf and Quartz.NET you’ve to get packages first:

install-package Topshelf  
install-package Topshelf.Quartz

Next step is to set up a hosting service in which we would like to execute Quartz’s job. Simple hosting console app looks like this:

namespace mpustelak.TopShelfAndQuartz
{
    class Program
    {
        static void Main(string[] args)
        {
            HostFactory.Run(x =>
            {
                x.Service<MyService>(s =>
                {
                    s.WhenStarted(service => service.OnStart());
                    s.WhenStopped(service => service.OnStop());
                    s.ConstructUsing(() => new MyService());
 
                    s.ScheduleQuartzJob(q =>
                        q.WithJob(() =>
                            JobBuilder.Create<MyJob>().Build())
                            .AddTrigger(() => TriggerBuilder.Create()
                                .WithSimpleSchedule(b => b
                                    .WithIntervalInSeconds(10)
                                    .RepeatForever())
                                .Build()));
                });
 
                x.RunAsLocalSystem()
                    .DependsOnEventLog()
                    .StartAutomatically()
                    .EnableServiceRecovery(rc => rc.RestartService(1));
 
                x.SetServiceName("My Topshelf Service");
                x.SetDisplayName("My Topshelf Service");
                x.SetDescription("My Topshelf Service's description");
            });
        }
    }
 
    public class MyService
    {
        public void OnStart()
        {
        }
 
        public void OnStop()
        {
        }
    }
 
    public class MyJob : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            Console.WriteLine($"[{DateTime.UtcNow}] Welcome from MyJob!");
        }
    }
}

First step is to execute HostFactory.Run(…) code which is responsible for hosting the Windows service (a console application).

Second step is to define how our service should behave. In this case I called it MyService. As an addition we may set up what should happen when the service starts and stops (OnStart and OnStop methods).

The next step is to initialize which constructor Quartz should be using. In this case it’s the default constructor. At this point, there is also the possibility to transfer that dependency onto the inversion of control container, and use i.e. ConstructUsingNinject for NInject (for more info check i.e. Topshelf.Ninject or Topshelf.StructureMap Nuget packages).

The last step is to define job scheduler’s execution. In presented example, it will run every 10 seconds (WithIntervalInSeconds(10)), without stopping (RepeatForever). MyJob implementation of IJob interface shows what’s going to happen every 10 seconds. It’ display current time and “Welcome from MyJob” text.

Check below how it looks like in the console once started:
Topshelf and Quartz.NET example

Summary

TopShelf and Quartz.NET allows us, developers, to rapidly build small (or even large) Windows services to execute scheduled jobs in .NET. As shown in this post, developers don’t need to understand the complexity of setting up Windows services and installing them on the machine via InstallUtil.

For more info about Topshelf and Quartz.NET, please reffer to documentation: Topshelf and Quartz.NET.

Published by

Mateusz Pustelak

Technical Lead at Iglu.com, Software Developer with several years of commercial experience, TDD practitioner, DDD/CQRS fan.

2 thoughts on “Scheduled jobs made easy – Topshelf and Quartz.NET”

Leave a Reply

Your email address will not be published. Required fields are marked *

*