Don’t you not like it one bit when users think that your application is sluggish? 

And you know that, you really cannot do anything about it, because it is interacting with third party services, tools, vendors, and is just doing way too many tasks and some of them really complex.

If you think, the user need not wait for the job to be completed and it can be executed in the background, but you do not want to use the tedious ways – Windows Service, MSMQ, and Thread…

Then, this is the blog you are looking for.

Hangfire helps to create background jobs in your web application with minimum effort.

What is Hangfire?

Hangfire is an open-source framework available as a Nuget Package. It provides options to create, view, process and manage background jobs. It supports persistent storage using MS SQL, Redis, PostgresSQL, MongoDB and Composite. It has an automatic retries feature, if there is any problem (both internal and external) during execution of a job. And it has an integrated dashboard UI which will be available at the hosted site. More details in Hangfire Dashboard section.

You can use Hangfire with any of the web framework of .net as does not have any dependency on System.Web: Asp.Net WebForms, MVC, WebAPI, etc. It is possible to use Hangfire in Console application and Windows Service too.

Installation

In Package manager console: Install-Package Hangfire (to install latest Hangfire)

To install .net version compatible Hangfire use: Install-Package Hangfire_net40 (for .net 4.0 framework)

Configuration

In web.config, for persistent storage, need to specify the connection string (where all tasks related information will be stored). Create a blank DB with the name“Hangfire_Blog”

<add name=”Hangfire_Blog” connectionString=”Data Source=localhost;Initial Catalog=Hangfire_Blog; User Id=sa; Password=password;” providerName=”System.Data.SqlClient”/>

 

In Startup.cs, you need add these statements.

UseSqlServerStorage – Parameter as Connectionstring name for persistent storage.

UseHangfireDashboard – To setup a UI Hangfire dashboard, this can be accessed with the hosted site URL as http://siteurl/hangfire

UseHangfireServer – To setup a new instance of BackgroundJobServer.

Or use var _backgroundJobServer = new BackgroundJobServer();

 

using Hangfire;

using Microsoft.Owin;

using Owin;

 

[assembly: OwinStartupAttribute(typeof(HangfireBlog.Startup))]

namespace HangfireBlog

{

public partial class Startup {

public void Configuration(IAppBuilder app) {

ConfigureAuth(app);

GlobalConfiguration.Configuration.UseSqlServerStorage(“Hangfire_Blog”);

app.UseHangfireDashboard();

app.UseHangfireServer();

}

}

}

 

Execute the application and following tables will be added to the database:

Types of Background Jobs

Fire-and-forget

This type of Job is executed only once and is triggered almost instantly after created.

var jobId = BackgroundJob.Enqueue(() => FireAndForget());

public void FireAndForget()

{

Console.WriteLine(“Fire and forget!”);

}

 

Delayed

This type of Job is executed only once and is triggered after a TimeSpan (specified interval of time).

var jobId = BackgroundJob.Schedule(() => Delayed(), TimeSpan.FromHours(3));

public void Delayed()

{

Console.WriteLine(“Delayed, Executed after 3 hours!”);

}

 

Continuations

This type of Job is executed when its specified parent job has finished its execution.

BackgroundJob.ContinueWith(parentJobId, () => ContinueWith());

public void ContinueWith()

{

Console.WriteLine(“Continue with, Child executed!”);

}

 

Recurring

This type of Job is executed multiple times and is triggered based upon the recurrence pattern (Hangfire.Cron type).

RecurringJob.AddOrUpdate(() => Recurring(), Cron.Weekly);

public void Recurring()

{

Console.WriteLine(“Recurring, Execute Weekly!”);

}

 

Batches

Contains a set of jobs and all are triggered only once.

var batchId = Batch.StartNew(b =>

{

b.Enqueue(() => Console.WriteLine(“Job 1”));

b.Enqueue(() => Console.WriteLine(“Job 2”));

});

public void Job1()

{

Console.WriteLine(“Job 1 Executed!”);

}

 

public void Job2()

{

Console.WriteLine(“Job 2 Executed!”);

}

 

Batch Continuations

This type of Job is executed when all background jobs in a parent batch has finished its execution.

Batch.ContinueWith(batchId, b =>

{

b.Enqueue(() => ContinueWith());

});

public void ContinueWith()

{

Console.WriteLine(“Batch – Continue with, Child executed!”);

}

 

Hangfire Dashboard

Hangfire dashboard provides graphs (real time graph, history graph with no. of jobs failed and succeeded) and basic info about the version of Hangfire, DB that it is connected to.  Jobs tab provides more information about the job data, job status, exception details and so on.

Let us create a job and look at the dashboard now.

Example: Add this to test project (page load).

 

BackgroundJob.Enqueue(() => FireAndForget());

public void FireAndForget()

{

Console.WriteLine(“HangfireBlog – Fire and forget!”);

}

This will create a job in the background and will be triggered immediately.

Let’s access dashboard, this is hosted in your localhost application (http://localhost:54596/hangfire) to see the job status.

1 job is scheduled and there was an exception hence, it is retries pool

Click on the link to see the exceptions:

Default No. of retries is 10, this is job will be tried 10 times before it will moved to Failed pool.

 

Following can be used, to specify the no. of retries:

[AutomaticRetry(Attempts = 0)]

public void FireAndForget()

{

Console.WriteLine(“HangfireBlog – Fire and forget!”);

}

If job is succeeded it will be moved to Succeeded pool.

Dashboard provides some graphs and basic info about the version of Hangfire, DB that it is connected to.

References

http://hangfire.io/overview.html

http://docs.hangfire.io/en/latest/background-processing/index.html

My next blog would be about background jobs on Azure WebApps using Azure WebJobs.