Scheduling background jobs using Hangfire in ASP.NET Core

Scheduling and monitoring background task is challenging work. Every big application needs to implement background tasks to accomplish background works like data processing, email reminders, process SMS queue and Email queues etc. Windows service is that the most typical approach to meet the necessity.

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

Hangfire is an open source library to schedule and execute background jobs in .NET application. you'll be able to create a simple background process inside the same application pool or thread without creating separate application. Hangfire create background jobs in persistence storage like MS SQL server, Redis, MongoDb and others, that may prevent from loosing job on recycling IIS pool or exception prevalence.

ASP.NET Core is now a common platform for MVC and Web API, 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 Package Management Console or Nuget package manager.

Intall 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 in the project.

Image 1: Nuget package manager
After successful installation, let's configure Hangfire.

Configuration

Open Startup.cs class and locate a ConfigureServices method to register Hangefire 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 will SQL Server. We must provide a connection string to locate SQL server database named HangFireDb. DefaultConnection is a connection string name added to appsettings.json file.
"ConnectionStrings": {
    "DefaultConnection": "Data Source=.\\SQLEXPRESS2014;Initial Catalog=HangFireDb;Integrated Security=True;"
  }
Once the service is configured,  navigate to Configure method to add below codes. Here, app.UseHangfireDashboard() will set up the dashboard 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 browser by hitting http://<website-url>/hangfire url.
Image 2: Hangfire Dashboard.
Hangfire offers 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 configured database and check for the required database schema. If schema doesn't exist, it creates schema. Below image shows a list of schemas created when running the application.

Image 3: Hangfire database schema

How it Works?

Hangfire handles different types of background jobs, and all of them are invoked in a separate execution context.
With Hangfire you can create
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 supported). The queue is listened by a couple of dedicated workers that 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 recurrent on every defined interval.You can define interval from milliseconds to year.
RecurringJob.AddOrUpdate(() => Console.WriteLine("Minutely Job executed"), Cron.Minutely);
Continuations
Continuations allow you to define complex workflows by chaining multiple background jobs together. Here second is Enqueued 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.

Image 4: A list of succeeded jobs
As you can see, dashboard gives meaningful information like a list of succeeded jobs with Id, name, executed time and duration. Re-queuing jobs features has been provided to re-fire selected job from the list.

Following are the screenshot for various kind of background jobs.
Image 5: Fire and forget job example


Image 6: Delayed job example


Image 7: Continuations job example


Image 8: Continuations dependent job example


Image 9:Recurring job example
Change the Dashboard Url
Be default Hangfire set http://<website-url>/hangfire to access the dashboard. It's easy to configure your custom url.
app.UseHangfireDashboard("/dashboard");
Access Remotely
Default Hangfire configuration set up for local environment only. To make Hangfire working on production environment, we need to implement custom IAuthorizationFilter. So our code changed to this.
app.UseHangfireDashboard("/dashboard", new DashboardOptions  
{ 
    Authorization = new [] { new HangireAuthorizationFilter() }
});
Everything will works fine now.😇

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

Download source code or fork on github

Summary

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

References 
- Hangfire official website 
- Hangfire overview
- Hangfire quick start
- Hangfire - GitHub