Explore Hangfire with .NET (C#)

Merwan Chinta
CodeNx
Published in
4 min readDec 22, 2023

Hangfire is an open-source library for .NET that enables developers to create, process, and manage background jobs in a .NET application.

What problems does Hangfire solve?

Asynchronous Task Execution: Hangfire allows tasks to be executed asynchronously. This means that long-running tasks, such as data processing, file uploads, or complex calculations, can be performed in the background, without blocking the main application thread.

Reliability and Persistence: Hangfire ensures that tasks are not lost if your application restarts or crashes. It does this by persisting jobs in a database, which means that tasks can be retried or continued after an application failure.

Scheduled Tasks: It supports not only immediate background tasks but also delayed and recurring tasks. This is useful for operations that need to occur at specific times or at regular intervals, like nightly data processing or periodic cleanup tasks.

Scalability: With Hangfire, you can scale your background processing horizontally by adding more processing servers. This is particularly useful for handling large volumes of tasks or when tasks are resource-intensive.

Task Management and Monitoring: Hangfire includes a dashboard for monitoring and managing background tasks. You can view the status of jobs (scheduled, processing, succeeded, failed), retry failed jobs, and get insights.

Decoupling of Task Submission and Processing: It allows the submission of tasks from one part of your application (like a web request handler) and their processing in a different part, potentially on a different server. This decoupling enhances the maintainability and scalability of the application.

Hangfire is designed to integrate seamlessly with the .NET ecosystem, allowing developers to write background tasks and use familiar tools and frameworks. Hangfire helps improve the responsiveness of applications, ensures the reliability of background task execution, and makes it easier to manage and scale background tasks.

Hangfire Dashboard — Image source from docs.hangfire.io

.NET Code Snippets with Hangfire

To use Hangfire in a .NET application, you need to install it via NuGet and set it up in your project.

Install-Package Hangfire
Install-Package Hangfire.SqlServer

Configure Hangfire in Startup.cs

In your Startup.cs, you'll need to configure Hangfire to use SQL Server for storage and add the Hangfire server.

public void ConfigureServices(IServiceCollection services)
{
// Other services...

// Configure Hangfire to use SQL Server storage
services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage("YourConnectionString", new SqlServerStorageOptions
{
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true
}));

// Add the Hangfire server
services.AddHangfireServer();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Other configurations...

// Use Hangfire dashboard
app.UseHangfireDashboard();

// Other middleware...
}

Assume we have a scenario where files are uploaded to a server, and we need to process these files — read, analyze, and then archive them.

Fire-and-Forget Task: File Upload Notification

Right after a file is uploaded, we want to log this event or send a notification.

public void FileUploaded(string fileName, IBackgroundJobClient backgroundJobs)
{
backgroundJobs.Enqueue(() => LogFileUpload(fileName));
}

public void LogFileUpload(string fileName)
{
// Logic to log the file upload
Console.WriteLine($"File uploaded: {fileName}");
}

Delayed Task: Begin File Analysis

After a file is uploaded, we might want to wait a bit before starting the analysis (e.g., to ensure the file is fully written and stable).

public void ScheduleFileAnalysis(string fileName, IBackgroundJobClient backgroundJobs)
{
backgroundJobs.Schedule(() => AnalyzeFile(fileName), TimeSpan.FromMinutes(10));
}

public void AnalyzeFile(string fileName)
{
// Logic to analyze the file
Console.WriteLine($"Analyzing file: {fileName}");
}

Recurring Task: Daily File System Cleanup

Every day, we want to clean up any temporary files or logs that are no longer needed.

public void ConfigureDailyCleanup()
{
RecurringJob.AddOrUpdate(
"daily-file-cleanup",
() => PerformDailyCleanup(),
Cron.Daily);
}

public void PerformDailyCleanup()
{
// Logic for daily cleanup
Console.WriteLine("Performing daily file system cleanup.");
}

Chaining Multiple Workflow Jobs: Complete File Processing Workflow

After a file is uploaded, we want to analyze it and then archive it. This is a chained workflow.

public void ProcessFile(string fileName, IBackgroundJobClient backgroundJobs)
{
var analyzeJobId = backgroundJobs.Enqueue(() => AnalyzeFile(fileName));
backgroundJobs.ContinueWith(analyzeJobId, () => ArchiveFile(fileName));
}

public void ArchiveFile(string fileName)
{
// Logic to archive the file
Console.WriteLine($"Archiving file: {fileName}");
}

Additional Notes

Ensure Proper Method Accessibility: The methods we are calling through Hangfire, like AnalyzeFile, LogFileUpload, etc., should be public and static if they are not part of the same class where we are creating the job. Hangfire needs to be able to access these methods from its processing context.

Error Handling: Always include robust error handling in background tasks, as exceptions in these tasks can sometimes be less visible than in foreground operations.

Security and Permissions: Ensure that the background job has the necessary permissions to perform file operations, especially when dealing with file systems on the server.

Testing and Monitoring: Utilize Hangfire dashboard to monitor these jobs.

API reference

For detailed information about Hangfire API, implementation specifics, and up-to-date resources, please visit the official Hangfire GitHub repository at Hangfire on GitHub.

Alternatives to Hangfire

Several alternatives to Hangfire offer similar functionality:

Quartz.NET: A full-featured, open-source job scheduling system that can be used from smallest apps to large-scale enterprise systems.

Azure Functions: If you are working in the Azure ecosystem, Azure Functions provide a serverless solution for running background jobs.

RabbitMQ + MassTransit: This combination can be used for more complex scenarios involving message queuing and background processing.

AWS Lambda: Similar to Azure Functions, but for the AWS ecosystem.

.NET Core Hosted Services: A simpler approach for background tasks, more integrated into .NET Core, but with less functionality compared to Hangfire.

What’s Next?

After setting up Hangfire, you may want to:

  • Explore advanced features of Hangfire like recurring jobs, delayed jobs, and job continuations.
  • Monitor and manage jobs using the Hangfire Dashboard.
  • Scale the background processing by configuring multiple job servers.
  • Implement error handling and retries for failed jobs.
  • Secure the Hangfire Dashboard if exposed to the web.
  • Consider persistence options for job storage, such as Redis or SQL Server, for production environments.

I trust this information has been valuable to you. 🌟 Wishing you an enjoyable and enriching learning journey!

📚 For more insights like these, feel free to 👏 follow 👉 Merwan Chinta

--

--

Merwan Chinta
CodeNx

🚧 Roadblock Eliminator & Learning Advocate 🖥️ Software Architect 🚀 Efficiency & Performance Guide 🌐 Cloud Tech Specialist