Pro Code Guide

Developer’s Guide To Programming

HOME    CONTACT   ABOUT

Hangfire in ASP.NET Core – Easy way to Schedule Background Jobs

Updated Mar 1, 2021 | 0 comments

This article covers detail about how to integrate Hangfire in ASP.NET Core applications which is an easy way to schedule background jobs in .NET Core and .NET based applications.

Background jobs or tasks allow the programmers to execute code on a different thread but scheduling & monitoring background jobs is a difficult task to achieve. Hangfire simplifies tasks to handle background jobs in ASP.NET Core.

Why or When to Schedule background jobs in .NET Core?

There might be some web requests which take lots of time for execution like generating a report on successful insertion or sending email/SMS as acknowledgment for the transaction completion. These requests can take an unknown amount of time to completion and keeping the user looking at the wait indicator for that time is not good handling of the request.

Idea is to unblock the user screen as soon as possible for requests which are going to take a long time to complete so that the user is able to perform other tasks. Though the user has been unblocked before the completion of long-running activities completion of these activities is also important as those are part of request business logic.

This is where background jobs come into the picture it’s like running the remaining of the activities in the background like on a different thread so that the main thread has been released for a user to perform other activities.

Introduction to Hangfire

Hangfire in ASP.NET Core

We saw the use of background jobs in our application but if we have to build a framework for background jobs creation & monitoring then it would be a complicated task that might require lots of effort. Also, this is a design feature and not a functional feature so spending too much time on this will not go down well with all the stakeholders. This is where Hangfire can be used.

Hangfire is a simple to use an open-source library that makes the implementation of background job easy in .NET Core & .NET Applications. Hangfire in ASP.NET Core allows the creation of background jobs and even provide monitoring features.

Hangfire in ASP.NET Core even supports persistent storage like Microsoft SQL Server, Redis (as part of Hangfire Pro), etc. for storing jobs information that prevents applications from losing jobs information in case of pool restarts. Storing the information of the jobs ensures that jobs are executed as per defined types & also jobs are retried if any exception occurs during the execution of the job.

Hangfire supports all the major logging frameworks and will log the complete job execution information to the logging destination configured for the application.

Hangfire provides reliability of background jobs by ensuring that jobs are executed at least once based on their scheduling criteria

Hangfire in ASP.NET Core application can be simple or distributed i.e. server/application that creates a job can be separate from the server/application that executes the job. This is possible as job information is stored on a database that can be shared between different servers/applications.

Types of background Jobs in Hangfire

With Hangfire in ASP.NET Core, you can create the following types of background Jobs

Fire and Forget

Fir and Forget jobs as the name suggests are executed only once and immediately as soon as they are created. These are mainly used to release the main thread so that the user experience is more responsive.

Delayed

As the name suggests these jobs are executed after some delay. This delay i.e. wait time is configurable and is queued upon creation. Execution is similar to fire & forget. This can be used for jobs that can be run outside the peak load window.

Recurring

These are scheduled jobs normally executed multiple times on every defined interval. The frequency of these jobs can be configured which can vary from milliseconds to years. These can be daily or weekly jobs to generate data dumps or reports.

Continuation

Continuation allows you to define a workflow i.e. you can configure multiple (parent-continuation job) background jobs that can be linked together based on completion of a parent job. i.e. the second job should execute provided that the first/parent job has executed correctly.

Additional job Types with Hangfire Pro

Batch Jobs

More than one background job can be linked together to form batch jobs together so that they all are executed together at the same time.

Batch Continuation

The link continuation job fires when the parent batch of jobs have completed i.e. all the jobs within a batch have completed then the continuation background job will fire.

Implement Hangfire in ASP.NET Core i.e. schedule background jobs in .NET Core

Here is the quick & short video to implement Hangfire in ASP.NET Core

Create a new ASP.NET Core WebAPI Project

For the implementation of Hangfire in ASP.NET Core let’s create a new ASP.NET Core Web API project in which we implement Hangfire.

I will be using Visual Studio 2019 community edition along with .NET Core 5 to create a new Web API project

  1. Launch Visual Studio 2019
  2. Select Create a new project on the initial screen as shown below

3. Next select ASP.NET Core Web Application from the displayed project types template list and click on the Next button as shown in the screenshot below

4. After that enter name for the project\solution as ProCodeGuide.Samples.Hangfire, provide a path of the project where it will be saved on the local disk & click on create button as shown below

5. Finally select .NET Core Framework as ASP.NET Core 5.0, application type as ASP.NET Core Web API, Enable OpenAPI Support for testing purpose & click on Create button as shown below

This will create the project and load the same in Visual Studio 2019 as shown in below screenshot

Install required Hangfire NuGet Packages

You will need to install the NuGet package Hangfire as shown below to include Hangfire references into your application.

Hangfire package in ASP.NET Core has a dependency on three other references which get installed along with Hangfire NuGet package as shown below

Configure Hangfire in Startup

Now that all the required NuGet packages for Hangfire has been installed we will not configure Hangfire in Startup.cs file.

We will add calls to the extension method AddHangfire & AddHangfireServer on the IServiceCollection in ConfigureServices method in class Startup.

public void ConfigureServices(IServiceCollection services)
{
    services.AddHangfire(x => x.UseSqlServerStorage("Server=(localdb)\mssqllocaldb;Database=ProCodeGuide.Samples.Hangfire;Trusted_Connection=True;MultipleActiveResultSets=true"));
    services.AddHangfireServer();

    //Remaining code has been removed for readability purposes
}

AddHangfire – This adds Hangfire in ASP.NET Core to the dependency injection container and takes an Action delegate using which we have set the connection string for SQL Server database to use SQL Server database as the storage for Hangfire Implementation.

Being a demo application I have hardcoded SQL Server connecting string in the startup class but that is not a good practice so please configure your SQL Server connection strings in the appsettings.json file and set it from there so that you have environment-specific SQL Server connection strings

AddHangfireServer – This adds Hangfire Server to the dependency injection container which will be used to configure and run jobs.

Adding Hangfire Dashboard UI

Now let’s add the middleware for Hangfire to the ASP.NET Core Middleware Pipeline that will be required to add the Hangfire dashboard UI. We will add a call to the extension method UseHangfireDashboard on the IApplicationBuilder instance.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseSwagger();
        app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ProCodeGuide.Samples.Hangfire v1"));
    }

    app.UseRouting();

    app.UseAuthorization();

    app.UseHangfireDashboard();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Check Hangfire Dashboard UI

Now that we have integrated Hangfire in ASP.NET Core application let’s run the application & check the dashboard for Hangfire.

You should see the below screen from swagger after building & running the application from visual studio.

Now after navigating to URL /Hangfire you should be able to see the dashboard for Hangfire in ASP.NET Core as shown below.

From dashboard UI you will be able to see scheduled jobs & monitor the status of jobs. The dashboard even allows you to manually run the jobs visible in the dashboard. The information available on the dashboard is as follows

Jobs – All the jobs stored in the database will be visible here under different status as Scheduled, Enqueued, Processing, Succeeded, Failed, Deleted & Awaiting.

Retries – Jobs list which have been retried due to some failure during previous execution.

Recurring Jobs – List of all the jobs which have been scheduled as recurring jobs can be seen.

Servers – All the Hangfire servers which have been added to the dependency injection container can be seen. These servers are responsible for processing jobs.

Please note that since Dashboard UI exposes application-specific sensitive data & even allows manual execution of jobs so it is important to secure access of this dashboard to authorized users only.

The only security provided by Hangfire in ASP.NET Core by default is that it allows only local requests for Dashboard UI

Hangfire Database

We did configure SQL Server database for Hangfire in ASP.NET Core as part of the Hangfire configuration in the startup (AddHangfire). When hangfire starts it looks for the required schema in the database if that does not exist then it will create the same as shown below

Hangfire database is used to for storing jobs information.

Create jobs with Hangfire in ASP.NET Core

To demonstrate different types of jobs in Hangfire in ASP.NET Core first let’s create a dummy service i.e. DummyEmailService, which implements interface IEmailService, that simulates mail sending by writing to console window that mail has been sent instead of sending actual mail.

Now if you want to implement a working email service that sends emails using MailKit Libraray & SMTP Server then you can read my other article on How to Send Emails in ASP.NET Core

Add interface Services/IEmailService.cs that has function SendEmail which will be implemented in dummy service DummyEmailService to write to console that email has been sent.

public interface IEmailService
{
    void SendEmail(string backGroundJobType, string startTime);
}

Add class Services/DummyEmailService that will implement interface IEmailService & will contain an implementation of SendEmail method to writing to console window.

public class DummyEmailService : IDummyEmailService
{
    public void SendEmail(string backGroundJobType, string startTime)
    {
        Console.WriteLine(backGroundJobType + " - " + startTime + " - Email Sent - " + DateTime.Now.ToLongTimeString());
    }
}

Now register this service in the application dependency injection container so that it can be injected into the controller. To add DummyEmailService to the container add the following line of code in Method ConfigureServices in Startup.cs file

services.AddTransient<IEmailService, DummyEmailService>();

Now let’s add a new API controller i.e. EmailController into which we will inject IEmailService to call method SendEmail from service in controller action method SendEmail.

[Route("[controller]")]
[ApiController]
public class EmailController : ControllerBase
{
    private IEmailService _emailService = null;
    public EmailController(IEmailService emailService)
    {
        _emailService = emailService;
    }

    [HttpGet]
    public string SendMail()
    {
        _emailService.SendEmail("Direct Call", DateTime.Now.ToLongTimeString());
        return "Email Initiated";
    }
}

Now run the application & you should be below screen when you navigate to URL /Email

Let’s look at how to implement each type of job in Hangfire in ASP.NET Core

Fire-and-Forget job

Hangfire.BackgroundJob.Enqueue is used to create the Fire-and-Forget background task. These jobs are executed almost immediately after creation and only once.

BackgroundJob.Enqueue(() => _emailService.SendEmail("Fire-and-Forget Job", DateTime.Now.ToLongTimeString()));

Delayed job

Hangfire.BackgroundJob.Schedule is used to create the Delayed background task. These jobs are created with a delay and are executed when the configured delay time has been elapsed.

BackgroundJob.Schedule(() => _emailService.SendEmail("Delayed Job",DateTime.Now.ToLongTimeString()),TimeSpan.FromSeconds(30));

Recurring Job

Hangfire.RecurringJob.AddOrUpdate is used to create the recurring background task. These can be every minute, daily or weekly jobs that get executed as per defined frequency.

RecurringJob.AddOrUpdate(() => _emailService.SendEmail("Recurring Job", DateTime.Now.ToLongTimeString()),Cron.Minutely);

Continuations job

Hangfire.BackgroundJob.ContinueJobWith is used to create the continuation background task. These jobs are executed immediately after the linked previous job has been successfully executed.

var jobId = BackgroundJob.Schedule(() => _emailService.SendEmail("Continuation Job 1", DateTime.Now.ToLongTimeString()), TimeSpan.FromSeconds(45));
BackgroundJob.ContinueJobWith(jobId, () => Console.WriteLine("Continuation Job 2 - Email Reminder - " + DateTime.Now.ToLongTimeString()));

Finally, I have modified the code in the SendMail action method in EmailController as shown below to demonstrate the execution pattern for each type of background job available in Hangfire in ASP.NET Core

[HttpGet]
public string SendMail()
{
    _emailService.SendEmail("Direct Call", DateTime.Now.ToLongTimeString());

    BackgroundJob.Enqueue(() => _emailService.SendEmail("Fire-and-Forget Job", DateTime.Now.ToLongTimeString()));

    BackgroundJob.Schedule(() => _emailService.SendEmail("Delayed Job", DateTime.Now.ToLongTimeString()),TimeSpan.FromSeconds(30));

    RecurringJob.AddOrUpdate(() => _emailService.SendEmail("Recurring Job", DateTime.Now.ToLongTimeString()),Cron.Minutely);

    var jobId = BackgroundJob.Schedule(() => _emailService.SendEmail("Continuation Job 1", DateTime.Now.ToLongTimeString()), TimeSpan.FromSeconds(45));
    BackgroundJob.ContinueJobWith(jobId, () => Console.WriteLine("Continuation Job 2 - Email Reminder - " + DateTime.Now.ToLongTimeString()));

    return "Email Initiated";
}

Let’s run the code & check the results

Now let’s run the code to check execution pattern of different type of jobs available in Hangfire in ASP.NET Core.

After running the application navigate to URL /Email this should call SendEmail to get action method in EmailController and the below screen should be displayed. But in background, all the configured job types should get created and triggered as per their execution pattern.

Let’s view the console window weather different type of jobs in Hangfire in ASP.NET Core have got triggered or not

We can see from above screen that all jobs were triggered as per their execution pattern.

Summary

In this article, we learn about background jobs, Hangfire in ASP.NET Core & the implementation of different types of jobs available in Hangfire in ASP.NET Core.

We also saw that there is even a paid version of Hangfire i.e. Hangfire Pro which supports Redis as a database & also supports some additional complex job types like batch & batch continuation.

I hope you liked this article, let me know your feedback in the comments section below

Download Source Code

Source code download link for implementation of Hangfire in ASP.NET Core

Hope you found this article useful. Your support is appreciated!
Buy me a coffeeBuy me a coffee
Home 9 Programming 9 Hangfire in ASP.NET Core – Easy way to Schedule Background Jobs

Set start URL in ASP.NET Core – Quick & Easy ways

This article will cover the ways to set start URL in ASP.NET Core 5 applications i.e. change the default URL (http://localhost:5000) in ASP.NET Core applications. When you create any new ASP.NET Core application whether its MVC App or Web API and run it then it will...

Hangfire in ASP.NET Core – Easy way to Schedule Background Jobs

This article covers detail about how to integrate Hangfire in ASP.NET Core applications which is an easy way to schedule background jobs in .NET Core and .NET based applications. Background jobs or tasks allow the programmers to execute code on a different thread but...

How to Send Emails in ASP.NET Core – Quick & Easy Guide

These days sending emails like user email id confirmation, OTP emails, acknowledgments, etc. is a very common requirement of any application. In this article, we will see a demo about how to send emails in ASP.NET Core in quick & easy steps. We will create an...

ML.NET – Machine Learning with .NET Core – Beginner’s Guide

This article will get you started with the fundamentals of Machine Learning and how to get started with Machine Learning with .NET Core i.e. ML.NET. We will even learn different concepts of Machine learning with a brief overview. Introduction to Machine Learning...

Implement Cookie Authentication in ASP.NET Core – Detailed Guide

This article will get you started with implementing cookie authentication in ASP.NET Core applications. Cookie authentication allows you to have your own login/register screens & custom logic for user-id/password validation without the need to use ASP.NET Core...

ASP.NET Core Identity Roles based Authorization

This article will get you started with what are ASP.NET Core Identity roles and the need for roles, how to enable ASP.NET Core Identity roles in MVC Application, and how to implement role-based authorization. Role-based authorization is for basic authorization where...

Dependency Injection in ASP.NET Core 3.1 – Beginner’s Guide

This article will cover in details dependency injection in ASP.NET Core 3.1. ASP.NET Core is designed from the ground up to support the dependency injection design pattern. Dependency injection in ASP.NET Core provides a technique to create applications that are...

Real-time Web Applications with SignalR in ASP.NET Core 3.1

In this article, we will learn about real-time web & how to build real-time web applications using SignalR in ASP.NET Core. As part of this article, we will work on an application that can send real-time messages/alerts to all connected users or private messages...

Code Profiling using MiniProfiler in ASP.NET Core 3.1

This article will get you started with how to enable miniprofiler in ASP.NET Core to measure the performance of your application. MiniProlifer helps you understand how your application is performing by allowing you to profile any part of code in ASP.NET Core...

Microservices with ASP.NET Core 3.1

Microservices is a type of Architecture in which application is created as multiple small independent serviceable components. This article will cover in detail how to create microservices with ASP.NET Core, Serilog, Swagger UI, Health Checks & Docker containers....

0 Comments

Submit a Comment

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