DEV Community

Mikael Krief
Mikael Krief

Posted on

The Hangfire Cookbook: A Practical Guide to Background Job Processing in .NET and Azure

Hangfire is one of the most powerful background job processing libraries in the .NET ecosystem. Whether you're working with ASP.NET Core, .NET Framework, or integrating with Azure Services, Hangfire simplifies job scheduling, execution, and monitoring.

This cookbook-style guide combines fundamental, advanced, and integration recipes for mastering Hangfire in real-world .NET applications. Each recipe provides a use case, step-by-step implementation, and best practices.


πŸ“Œ Chapter 1: Getting Started with Hangfire

1.1 Installing and Configuring Hangfire

Use Case

You need to set up Hangfire to handle background jobs in your .NET application.

Implementation

  1. Install Hangfire via NuGet
   Install-Package Hangfire
   Install-Package Hangfire.SqlServer
Enter fullscreen mode Exit fullscreen mode
  1. Configure Hangfire in Program.cs (for .NET Core)
   builder.Services.AddHangfire(config => 
       config.UseSqlServerStorage("your_connection_string"));
   builder.Services.AddHangfireServer();
   app.UseHangfireDashboard();
Enter fullscreen mode Exit fullscreen mode
  1. Enqueue a Test Job
   BackgroundJob.Enqueue(() => Console.WriteLine("Hello from Hangfire!"));
Enter fullscreen mode Exit fullscreen mode

Best Practices

βœ” Use a persistent database like SQL Server or Redis instead of in-memory storage.

βœ” Secure the Hangfire dashboard to prevent unauthorized access.


1.2 Job Types in Hangfire

Use Case

You want to execute different types of jobs such as one-time, delayed, recurring, or continuation jobs.

Implementation

βœ” Fire-and-Forget Jobs

BackgroundJob.Enqueue(() => SendEmail("user@example.com"));
Enter fullscreen mode Exit fullscreen mode

βœ” Delayed Jobs

BackgroundJob.Schedule(() => GenerateReport(), TimeSpan.FromMinutes(30));
Enter fullscreen mode Exit fullscreen mode

βœ” Recurring Jobs

RecurringJob.AddOrUpdate("daily-report", () => GenerateDailyReport(), Cron.Daily);
Enter fullscreen mode Exit fullscreen mode

βœ” Continuation Jobs

var jobId = BackgroundJob.Enqueue(() => ProcessOrder());
BackgroundJob.ContinueWith(jobId, () => NotifyCustomer());
Enter fullscreen mode Exit fullscreen mode

Best Practices

βœ” Use queues for prioritizing job execution.

βœ” Set timeouts and automatic retries to handle failures.


πŸ“Œ Chapter 2: Advanced Hangfire Techniques

2.1 Handling Job Failures and Retries

Use Case

You need to handle job failures gracefully and implement custom retry mechanisms.

Implementation

βœ” Customize Retries

[AutomaticRetry(Attempts = 3, OnAttemptsExceeded = AttemptsExceededAction.Fail)]
public void SendEmail()
{
    throw new Exception("SMTP server down!");
}
Enter fullscreen mode Exit fullscreen mode

βœ” Log Failed Jobs

public class LogFailureFilter : JobFilterAttribute, IServerFilter
{
    public void OnPerformed(PerformedContext context)
    {
        if (context.Exception != null)
        {
            Console.WriteLine($"Job {context.BackgroundJob.Id} failed: {context.Exception.Message}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
GlobalConfiguration.Configuration.UseFilter(new LogFailureFilter());
Enter fullscreen mode Exit fullscreen mode

Best Practices

βœ” Monitor failed jobs in the Hangfire Dashboard.

βœ” Implement job continuation for failure handling.


2.2 Using Dependency Injection in Jobs

Use Case

You need to use services like Entity Framework, Email Services, or APIs in Hangfire jobs.

Implementation

βœ” Resolve Services with IServiceScopeFactory

public class OrderProcessor
{
    private readonly IServiceScopeFactory _scopeFactory;

    public OrderProcessor(IServiceScopeFactory scopeFactory)
    {
        _scopeFactory = scopeFactory;
    }

    public void ProcessOrders()
    {
        using var scope = _scopeFactory.CreateScope();
        var dbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
        var orders = dbContext.Orders.Where(o => o.Status == "Pending").ToList();

        foreach (var order in orders)
            order.Status = "Processed";

        dbContext.SaveChanges();
    }
}
Enter fullscreen mode Exit fullscreen mode

βœ” Enqueue Job

BackgroundJob.Enqueue<OrderProcessor>(job => job.ProcessOrders());
Enter fullscreen mode Exit fullscreen mode

Best Practices

βœ” Avoid directly injecting DbContext; always use scoped services.

βœ” Implement transactional processing to avoid partial updates.


πŸ“Œ Chapter 3: Using Hangfire in Azure

3.1 Storing Hangfire Jobs in Azure SQL

Use Case

You need to persist Hangfire jobs in Azure for scalability and reliability.

Implementation

βœ” Configure Hangfire to Use Azure SQL

GlobalConfiguration.Configuration.UseSqlServerStorage("Azure_SQL_Connection_String");
Enter fullscreen mode Exit fullscreen mode

Best Practices

βœ” Use Azure SQL with Read Replicas to balance the load.


3.2 Processing Jobs with Azure Storage Queues

Use Case

You want to offload Hangfire jobs to Azure Storage Queues for better scalability.

Implementation

βœ” Push Jobs to Azure Queue

var queueClient = new QueueClient("Azure_Storage_Connection_String", "job-queue");
queueClient.SendMessage("Start Processing Order");
Enter fullscreen mode Exit fullscreen mode

βœ” Process Queue Messages with Hangfire

BackgroundJob.Enqueue(() => ProcessQueueMessage());
Enter fullscreen mode Exit fullscreen mode

Best Practices

βœ” Use Azure Service Bus for complex job orchestration.


πŸ“Œ Conclusion

This Hangfire Cookbook covered:

βœ… Job scheduling & execution

βœ… Advanced job processing techniques

βœ… Integrating Hangfire with SignalR & Azure

βœ… Security & performance best practices

Want to go further? Next article : Running Hangfire in Kubernetes (AKS) or Microservices! πŸš€

Image of Quadratic

Chat with your data and get insights in seconds

Leverage native spreadsheet AI to write Python, SQL, and JavaScript for quick insights and complex analysis.

Try Quadratic free

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay