Background Tasks using Hangfire

What Is Hangfire?

Hangfire is a library that gives you the possibility to run scheduled tasks in the background without the interaction of the UI thread.

This library is very similar to CRON jobs or the SQL Server Agent, so you can schedule different tasks.

Millions of projects use it and it’s free. There is also a premium version available if you need batches, but I will show you an alternative.

Hangfire offers a dashboard interface where you can see the failed tasks, the scheduler, and the successful jobs.

Hangfire Dashboard

Hangfire Configuration

First, you must install the Nuget packages.

Install-Package Hangfire
Install-Package Hangfire.SqlServer
Install-Package Hangfire.AspNetCore

For storage, there are multiple options: SQL Server, Azure database, Memory storage, Redis, PostgreSQL, MongoDB, and others.

Hangfire can be used in multiple types of .NET projects. In ASP.NET Core, it offers dependency injection support.

Hangfire is very simple to configure in ASP.NET Core.

public void ConfigureServices(IServiceCollection services)
{
	services.AddHangfire(configuration => configuration
	.UseSimpleAssemblyNameTypeSerializer()
	.UseRecommendedSerializerSettings()
	.UseSqlServerStorage(Configuration.GetConnectionString("DefaultConnection"), new SqlServerStorageOptions
	{
		CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
		SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
		QueuePollInterval = TimeSpan.Zero,
		UseRecommendedIsolationLevel = true,
		UsePageLocksOnDequeue = true,
		DisableGlobalLocks = true
	}));
	
	services.AddHangfireServer();
}

Types of jobs

There are six types of jobs that Hangfire supports:

Fire-and-forget jobs

The jobs are executed right after creation on a separated thread.

string jobId = BackgroundJob.Enqueue(() => _transactionRepo.ProcessTransaction(transaction.Id));

Continuations jobs

Using this feature you can schedule a job to start after another finishes

string jobId = BackgroundJob.Enqueue(() => _transactionRepo.ProcessTransaction(transaction.Id));
BackgroundJob.ContinueJobWith(jobId, () => _bonusRepo.CalculateBonus(transaction.Id));

Delayed jobs

Delayed jobs are useful when you interact with different services and you have to run a task with a delay.

var jobId = BackgroundJob.Schedule(() => _bitcoinWalletService.GetAmount(),TimeSpan.FromMinutes(5));

Recurring Jobs

These are useful when you need to do a task repeatedly. For example, you want to clear the logs every month or you need to do some calculations.

var jobId = BackgroundJob.AddOrUpdate(() => _logsRepo.ClearLogs(), Cron.Monthly);

Batches Jobs

Batches jobs are available in the premium version of Hangfire. It allows to enqueue multiple jobs at the same time.

var batchId = BatchJob.StartNew(b =>
{
    b.Enqueue(() => _transactionRepo.ProcessTransaction(transactions[0].Id));
    b.Enqueue(() => _transactionRepo.ProcessTransaction(transactions[1].Id));
});

An alternative for this paid feature is to start a task and add more jobs inside. The problem with this approach is that the jobs will not be considered a single unit of work, but the advantage is that you will not block the UI thread when you add the tasks.

_ = Task.Run(async () =>{
foreach (var transaction in transactions)
{
    string jobId = BackgroundJob.Enqueue(() => _transactionRepo.ProcessTransaction(transactions[i].Id));
}
});

Hangfire alternatives

There are many alternatives for scheduled jobs, starting from built-in features of the .NET like Tasks, Threads, and Hosted Services. Sometimes these built-in classes are very useful, but it is easier to schedule a task using a library that can record the successful and failed jobs.

Quartz.NET

Quartz is more advanced and complex than Hangfire. It offers support for job persistence.

One con of the Quartz.NET library is that it is a port of the Java Library. This is a con because it has more complexity. For example, any background task should be defined in a class that implements the IJob interface.

Another con is that Quartz library doesn’t have included a UI dashboard for tasks’ management and logs. On the other part, some libraries offer this enhancement.

FluentScheduler

FluentScheduler is not as complex as Quartz and less advance than Hangfire.

The biggest con of this library is that it doesn’t save the state of jobs. There is no persistence storage for the jobs. This a big reason why that people don’t use it.

1 thought on “Background Tasks using Hangfire”

Leave a Comment