Schedule Background Jobs Using Hangfire In ASP.NET Core

Scheduling and monitoring background tasks is challenging work. Every big application needs to implement background tasks to accomplish background work, such as data processing, email reminders, SMS queues, and email queues. Windows Service is the most typical approach to meet the necessity.

Today, we are going to set up Hangfire and write some code to schedule an initial job in the ASP.NET Core project.

Hangfire is an open-source library that schedules and executes background jobs in .NET applications. You'll be able to create a simple background process inside the same application pool or thread without creating separate applications. Hangfire creates background jobs in persistence storage, like MS SQL Server, Redis, MongoDB, and others, that may prevent you from losing the job of recycling IIS pools or exception prevalence.

ASP.NET Core is now a common platform for MVC and Web API, with no separate project creation needed. Let's create a new ASP.NET Core MVC project. After the project is created, install Hangfire from NuGet. You can install Hangfire either from the Package Management Console or NuGet Package Manager.

Install via NuGet

PM> Install-Package HangFire

We are going to install Hangfire using NuGet Package Manager. Search the Hangfire stable version(current 1.6.7) and install it in the project.

Image 1. Nuget package manager

After successful installation, let's configure Hangfire.

Configuration

Open the Startup.cs class and locate a ConfigureServices method to register Hangfire as a service.

public void ConfigureServices(IServiceCollection services)
{
    // Add Hangfire services.
    services.AddHangfire(x => x.UseSqlServerStorage(Configuration.GetConnectionString("DefaultConnection")));
    
    // Add framework services.
    services.AddMvc();
}

Here, we are registering Hangfire with SQL Server. We must provide a connection string to locate the SQL Server database named HangFireDb. DefaultConnection is a connection string name added to the appsettings.json file.

"ConnectionStrings": {
    "DefaultConnection": "Data Source=.\\SQLEXPRESS2014;Initial Catalog=HangFireDb;Integrated Security=True;"
}

Once the service is configured, navigate to the Configure method to add the codes below. Here, app.UseHangfireDashboard() will set up the dashboard. While http://<website-url>/hangfire, and app.UseHangfireServer() will register a new instance for BackgroundJobServer.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();
    
    app.UseHangfireDashboard();
    app.UseHangfireServer();
    
    app.UseDeveloperExceptionPage();
    app.UseBrowserLink();
    
    app.UseStaticFiles();
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

Now, let's run the application. Hangfire dashboard is available in the browser by hitting http://<website-url>/hangfire url.

Hangfire Dashboard

Image 2. Hangfire Dashboard

Hangfire offers an integrated web monitoring UI, which is used to control any aspect of background job processing, as well as statistics, exceptions, and background job history.

When the Hangfire Server starts, it'll look for a configured database and check for the required database schema. If the schema doesn't exist, it creates a schema. The below image shows a list of schemas created when running the application.

Hangfire Database

Image 3. Hangfire database schema

How does it work?

Hangfire handles different types of background jobs, and all of them are invoked in a separate execution context.

With Hangfire, you can create the following.

  • Fire and forget: Fire and forget jobs are executed once on an immediate basis after creation. Once you create a fire-and-forget job, it is saved to its queue ("default" by default, but multiple queues are supported). The queue is listened to by a couple of dedicated workers who fetch a job and perform it.
    BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget Job Executed"));
    
  • Delayed: After the given delay, the job will be put in its queue and invoked as a regular fire-and-forget job.
    BackgroundJob.Schedule(() => Console.WriteLine("Delayed job executed"), TimeSpan.FromMinutes(1));
    
  • Recurring: Recurring jobs will recur on every defined interval. You can define intervals from milliseconds to years.
    RecurringJob.AddOrUpdate(() => Console.WriteLine("Minutely Job executed"), Cron.Minutely);
    
  • Continuations: Continuations allow you to define complex workflows by chaining multiple background jobs together. Here, the second job is queued with the first job.
    var id = BackgroundJob.Enqueue(() => Console.WriteLine("Hello, "));
    BackgroundJob.ContinueWith(id, () => Console.WriteLine("world!"));
    

After running the application, we have interesting results in a dashboard.

Succeesd Job

Image 4. A list of succeeded jobs

As you can see, the dashboard gives meaningful information like a list of successive jobs with Id, name, executed time, and duration. A re-queuing jobs feature has been provided to re-fire selected jobs from the list.

The following are the screenshots for various kinds of background jobs.

Console

Image 5. Fire and forget job example

 Delayed job

Image 6. Delayed job example

 Continuations job

Image 7. Continuations job example

 Dependent job

Image 8. Continuations dependent job example

Recurring job

Image 9. Recurring job example

  • Change the Dashboard URL: By default, Hangfire is set to http://<website-url>/hangfire to access the dashboard. It's easy to configure your custom URL.
    app.UseHangfireDashboard("/dashboard");
    
  • Access Remotely: The default Hangfire configuration is set up for the local environment only. To make Hangfire work in the production environment, we need to implement a custom IAuthorizationFilter. So, our code is now changed to this.
    app.UseHangfireDashboard("/dashboard", new DashboardOptions
    {
        Authorization = new[] { new HangfireAuthorizationFilter() }
    });
    

Everything will work fine now.

That's all. You can find the detailed documentation on the official Hangfire website. You can fork the Hangfire project and make contributions on GitHub.

Download source code or fork on github.

Summary

In this article, we've learned how to configure Hangfire in ASP.NET Core. We composed some code to queue the background jobs using Hangfire in ASP.NET Core. I emphatically favor Hangfire, as it is very easy to implement, and the dashboard allows you to monitor and control any aspect of background job processing, as well as statistics, exceptions, and background job history.

References

Author link: Scheduling background jobs using Hangfire in ASP.NET Core.