Hangfire Implementing Background Jobs

Hangfire is a robust library for managing background jobs in .NET applications, allowing developers to easily create and manage tasks that run asynchronously.

Whether you're scheduling recurring tasks, executing one-off jobs, or managing time-consuming operations without blocking the main thread, Hangfire provides a flexible and reliable solution. In this article, we'll walk through setting up Hangfire to automatically clean up expired JWT tokens from a database, ensuring your authentication system remains efficient and secure.

Requirements

Before we dive into the implementation, make sure you have the following:

  • At least .NET 6.0 SDK installed
  • A basic understanding of .NET and C#
  • A running SQL Server instance
  • Visual Studio or any preferred C# IDE

Setting Up the Project

Open your terminal or command prompt and run the following commands to create a new .NET web application:

dotnet new webapi -n HangfireBackgroundJob
cd HangfireBackgroundJob

Install Hangfire

Add Hangfire and its SQL Server storage package to your project:

dotnet add package Hangfire
dotnet add package Hangfire.SqlServer

Configure Hangfire

Open Startup.cs (or Program.cs if you're using the new minimal hosting model) and configure Hangfire in the ConfigureServices method:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    // Configure Hangfire to use SQL Server storage
    services.AddHangfire(configuration => 
        configuration.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
                     .UseSimpleAssemblyNameTypeSerializer()
                     .UseRecommendedSerializerSettings()
                     .UseSqlServerStorage("Server=your_server;Database=your_database;User Id=your_user;Password=your_password;", new SqlServerStorageOptions
                     {
                         CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
                         SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
                         QueuePollInterval = TimeSpan.FromSeconds(15),
                         UseRecommendedIsolationLevel = true,
                         DisableGlobalLocks = true
                     }));

    services.AddHangfireServer();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();
    app.UseAuthorization();

    // Use Hangfire Dashboard (optional for monitoring jobs)
    app.UseHangfireDashboard();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Creating the Background Job

Now, let's create a background job that deletes expired JWT tokens from the database.

Create a Service for Token Cleanup

First, create a service that will handle the token cleanup logic. Add a new class called TokenCleanupService.cs:

using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;

public sealed class TokenCleanupService
{
    private readonly ApplicationDbContext _context;
    private readonly ILogger<TokenCleanupService> _logger;

    public TokenCleanupService(ApplicationDbContext context, ILogger<TokenCleanupService> logger)
    {
        _context = context;
        _logger = logger;
    }

    public async Task CleanUpExpiredTokensAsync()
    {
        var expiredTokens = await _context.JwtTokens
            .Where(t => t.ExpirationDate < DateTime.UtcNow)
            .ToListAsync();

        if (expiredTokens.Any())
        {
            _context.JwtTokens.RemoveRange(expiredTokens);
            await _context.SaveChangesAsync();
            _logger.LogInformation("Deleted {count} expired tokens.", expiredTokens.Count);
        }
    }
}

Schedule the Background Job

Open Startup.cs or Program.cs and schedule the background job using Hangfire:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IRecurringJobManager recurringJobManager)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();
    app.UseAuthorization();

    app.UseHangfireDashboard();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });

    // Schedule the token cleanup job to run daily at midnight
    recurringJobManager.AddOrUpdate(
        "TokenCleanup",
        () => new TokenCleanupService().CleanUpExpiredTokensAsync(),
        Cron.Daily);
}

Running and Monitoring the Job

Start your application by running

dotnet run

Navigate to http://localhost:5000/hangfire to view the Hangfire Dashboard and monitor your jobs.

Verify the Job Execution

Check your database to ensure expired tokens are being deleted as expected. You can also view the job logs in the Hangfire Dashboard to verify successful execution.

Conclusion

Using Hangfire to manage background jobs in a .NET application is a straightforward and efficient way to handle tasks that need to run asynchronously.

In this hands-on guide, we've set up a Hangfire project and created a background job to clean up expired JWT tokens from a database.

This ensures that your authentication system remains clean and performant without blocking your application's main thread. Hangfire's flexibility and ease of use make it an excellent choice for managing background tasks in any .NET application.

Love Discord?