Background jobs are essential in modern applications to handle tasks asynchronously without blocking the main application thread. These tasks include sending emails, processing payments, cleaning up logs, and more. In .NET Core, Hangfire is a popular library that simplifies background job processing.
In this article, we will cover:
- Setting up Hangfire in a .NET Core application
- Implementing delayed and scheduled background jobs
- Persisting jobs using SQL Server
By the end, you will have a fully functional background job processing system in your .NET Core application.
1. What is Hangfire?
Hangfire is an open-source library that allows you to execute background jobs in .NET applications. It provides a simple API for enqueuing background tasks while ensuring reliability and scalability. The key features include:
- Persistent job storage (SQL Server, Redis, etc.)
- Support for fire-and-forget, delayed, scheduled, and recurring jobs
- An intuitive dashboard to monitor and manage jobs
Installation: Hangfire can be installed using NuGet:
Install-Package Hangfire
Install-Package Hangfire.SqlServer
2. Setting Up Hangfire in .NET Core
2.1 Configure Services
In Program.cs, add the necessary configurations to integrate Hangfire with SQL Server:
using Hangfire;
using Hangfire.SqlServer;
var builder = WebApplication.CreateBuilder(args);
// Configure Hangfire to use SQL Server
builder.Services.AddHangfire(config => config.UseSqlServerStorage("Server=.;Database=HangfireDB;Integrated Security=True;"));
builder.Services.AddHangfireServer();
var app = builder.Build();
// Use Hangfire dashboard
app.UseHangfireDashboard();
app.MapGet("/", () => "Hangfire in .NET Core");
app.Run();
2.2 Creating the Database for Hangfire
Run the following command in your package manager console to apply Hangfire migrations:
dotnet ef migrations add HangfireInit
dotnet ef database update
This will create necessary tables in HangfireDB for job storage.
3. Implementing Background Jobs
Hangfire provides different types of jobs:
3.1 Fire-and-Forget Job
Fire-and-forget jobs execute immediately after being enqueued.
BackgroundJob.Enqueue(() => Console.WriteLine("This is a fire-and-forget job!"));
3.2 Delayed Job
Delayed jobs execute after a specified delay.
BackgroundJob.Schedule(() => Console.WriteLine("This job runs after a delay."), TimeSpan.FromMinutes(5));
3.3 Recurring Job
Recurring jobs run at specified intervals using CRON expressions.
RecurringJob.AddOrUpdate("my-recurring-job", () => Console.WriteLine("This job runs every minute."), Cron.Minutely);
3.4 Continuation Job
A continuation job starts after a parent job completes.
var parentJobId = BackgroundJob.Enqueue(() => Console.WriteLine("Parent job"));
BackgroundJob.ContinueJobWith(parentJobId, () => Console.WriteLine("Continuation job"));
4. Implementing Job Persistence with SQL Server
4.1 Adding SQL Server Storage
Ensure that Hangfire is using SQL Server for job storage. We configured this earlier in Program.cs:
builder.Services.AddHangfire(config => config.UseSqlServerStorage("Server=.;Database=HangfireDB;Integrated Security=True;"));
4.2 Verifying Job Persistence
- Start your application and navigate to
/hangfire
to access the Hangfire Dashboard. - Trigger a job and check if it appears in the SQL Server Database.
Run the following query to view persisted jobs:
SELECT * FROM Hangfire.Job
If jobs are correctly stored, Hangfire is successfully persisting background jobs in SQL Server.
5. Monitoring and Managing Jobs
The Hangfire Dashboard provides a web-based UI to monitor jobs. Enable it in Program.cs
:
app.UseHangfireDashboard();
Now, navigate to:
http://localhost:5000/hangfire
You can monitor job statuses, retry failed jobs, and manually trigger jobs.
6. Best Practices for Hangfire Implementation
6.1 Use Dependency Injection
Ensure background jobs use services via dependency injection:
public class EmailService
{
public void SendEmail(string email)
{
Console.WriteLine($"Sending email to {email}");
}
}
Register the service:
builder.Services.AddSingleton<EmailService>();
Enqueue a job using DI:
BackgroundJob.Enqueue<EmailService>(emailService => emailService.SendEmail("user@example.com"));
6.2 Handle Job Failures
Use retries and error handling in Hangfire:
BackgroundJob.Enqueue(() => ProcessDataWithRetry());
[AutomaticRetry(Attempts = 5)]
public void ProcessDataWithRetry()
{
throw new Exception("Simulated failure");
}
6.3 Secure the Hangfire Dashboard
Protect Hangfire UI with authentication:
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
Authorization = new[] { new Hangfire.Dashboard.BasicAuthAuthorizationFilter() }
});
Conclusion
In this article, we implemented background jobs in .NET Core using Hangfire, focusing on:
- Fire-and-forget, delayed, and scheduled tasks
- Job persistence using SQL Server
- Best practices for robust background job processing
With this setup, your application can efficiently handle asynchronous operations, ensuring scalability and performance.