Asynchronous jobs made easy in .NET Core

Alexandru Dragan
METRO SYSTEMS Romania
3 min readSep 17, 2019
  1. Introduction

Sometimes a project needs to perform asynchronous operations now and then and has to rely on scheduler library. For the .NET world the most used libraries I know about are Quartz.NET and Hangfire.

2. The issue

When working with .NET framework the natural choice was Quartz.NET — Quartz Enterprise Scheduler .NET, but when we have upgraded .NET Core 2.x, serious issues with the .NET Core’s dependency injection emerged.

After battling a while to make Quartz work, I have finally switched to Hangfire which proved to be a very nice and easy to use library.

3. Setup

Most of the setup is done in Startup.cs as shows below:

Full source: https://gist.github.com/Alexei000/0ea37edb1a424bf18978184ce3bcb12a

You should pay attention to setting up how Hangfire persists and polls data from your data storage (in my case SQL Server, but other data storage can be used) especially to QueuePollInterval. Failing to put reasonable high values here will generate a lot of activity against the data storage (quickly check by using a profiler).

When application starts, PrepareSchemaIfNecessary = true ensures that Hangfire automatically creates all the required tables:

Hangfire tables

One nice feature is that Hangfire relies on NCronTab for specifying job run schedule and this allows to go beyond the classical Cron jobs minute resolution (e.g. can specify to run a job twice per minute if needed)

4. Usage

As already shown in the setup phase, scheduling a recurring job is a breeze if you have some CRON expressions knowledge.

Simple recurring job

This will schedule a job at exactly 17:10 each day. Also, you can provide any function to be executed (no interfaces to be implemented) and the code will be executed. All services defined through .NET Core’s dependency injection configuration will simply work as expected.

Another nice feature is that, if the job execution is skipped, it will run the job (sometimes is not desired) and it also has an implicit retrial mechanism (failure will have the job to be retried three times).

For very simple tasks like fire and forget, that also might use dependency injection it can be as simple as this:

BackgroundJob.Enqueue(() => myCustomService.Run());

A special case is configuring IIS to always run in order for the jobs to fire as configured (by default, it stops after 20 minutes of being idle).

5. Dashboard

A very useful feature is a dashboard that allows to quickly see the activity, what jobs are configured, manual trigger of jobs and more:

6. Conclusion

If you do not need a fancy scheduling system in ASP.NET Core, Hangfire is a good solution. For further details you can consult Hangfire docs.

--

--

Alexandru Dragan
METRO SYSTEMS Romania

A full-stack developer working with ASP.NET Core and Angular 2+. Also interested in knowledge-management.