Skip to footer content
.NET HELP

Hangfire .NET Core (How It Works For Developers)

Modern application development often requires processing background tasks to handle huge workloads. In such scenarios, we need background job handlers capable of executing multiple jobs. One such background job handler for C# .NET Core applications is Hangfire. In this blog, we are going to learn about managing Hangfire background jobs and how to use them with other packages like IronPDF for PDF Generation to generate PDF documents in the background.

Hangfire simplifies the implementation of background processing in ASP.NET Core or .NET Core 6 Web API applications by providing a reliable and flexible framework for managing and executing background jobs. Hangfire is available as a NuGet package and can be installed using the .NET CLI as shown below:

dotnet add package Hangfire --version 1.8.6

Implementation in .NET Core Web API

To learn about Hangfire, let's create a simple .NET Core API application and install Hangfire using the CLI.

dotnet new webapi -n HangfireDemo
cd HangfireDemo
dotnet build
dotnet add package Hangfire --version 1.8.6
dotnet build
dotnet new webapi -n HangfireDemo
cd HangfireDemo
dotnet build
dotnet add package Hangfire --version 1.8.6
dotnet build
SHELL

Here we are creating a simple weather REST API using .NET CLI. The first line creates a .NET Core Web API project named HangfireDemo to execute API endpoints. The second line navigates to our newly created folder "HangfireDemo," and then we build the project. Next, we add the Hangfire NuGet package to our project and build it again. After this, you can open your project in any editor of your choice, such as Visual Studio 2022 or JetBrains Rider. Now if you run the project you can see the Swagger as follows:

Hangfire .NET Core (How It Works For Developer): Figure 1 - Swagger

Here we can see the weather GET APIs, which return date, summary, and temperature.

Hangfire .NET Core (How It Works For Developer): Figure 2 - Weather GET API

Now let us add a Hangfire background job processor. Open the project in Visual Studio.

Add Hangfire Job Processor

Configure Hangfire in your application, typically in the Startup.cs file. This involves setting up a job storage and initializing the Hangfire server.

// Startup.cs
using Hangfire;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Add Hangfire services and use SQL Server as storage option
        services.AddHangfire(config => config.UseSqlServerStorage("your_connection_string"));
        services.AddHangfireServer();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        // Use Hangfire Server and Dashboard for monitoring and managing jobs
        app.UseHangfireServer();
        app.UseHangfireDashboard();
        // Your other configuration settings
    }
}
// Startup.cs
using Hangfire;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Add Hangfire services and use SQL Server as storage option
        services.AddHangfire(config => config.UseSqlServerStorage("your_connection_string"));
        services.AddHangfireServer();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        // Use Hangfire Server and Dashboard for monitoring and managing jobs
        app.UseHangfireServer();
        app.UseHangfireDashboard();
        // Your other configuration settings
    }
}
' Startup.cs
Imports Hangfire

Public Class Startup
	Public Sub ConfigureServices(ByVal services As IServiceCollection)
		' Add Hangfire services and use SQL Server as storage option
		services.AddHangfire(Function(config) config.UseSqlServerStorage("your_connection_string"))
		services.AddHangfireServer()
	End Sub

	Public Sub Configure(ByVal app As IApplicationBuilder, ByVal env As IHostingEnvironment)
		' Use Hangfire Server and Dashboard for monitoring and managing jobs
		app.UseHangfireServer()
		app.UseHangfireDashboard()
		' Your other configuration settings
	End Sub
End Class
$vbLabelText   $csharpLabel

The ConfigureServices method is used to add storage to save Hangfire's newly created jobs. Here, a SQL Server database is used. The SQL Server connection string should be replaced with "your_connection_string". One can also use in-memory storage with Hangfire.InMemory.

dotnet add package Hangfire.InMemory --version 0.6.0

And replace with:

services.AddHangfire(configuration => { configuration.UseInMemoryStorage(); });
services.AddHangfire(configuration => { configuration.UseInMemoryStorage(); });
services.AddHangfire(Sub(configuration)
	configuration.UseInMemoryStorage()
End Sub)
$vbLabelText   $csharpLabel

Create Background Jobs

Define the methods you want to run as background jobs. These methods should be static or instance methods of a class with a parameterless constructor. Jobs can be run as recurring jobs, or you can run multiple jobs simultaneously.

public class MyBackgroundJob
{
    public void ProcessJob()
    {
        // Background job logic, can be a recurring job or multiple jobs
        Console.WriteLine("Background job is running...");
    }
}
public class MyBackgroundJob
{
    public void ProcessJob()
    {
        // Background job logic, can be a recurring job or multiple jobs
        Console.WriteLine("Background job is running...");
    }
}
Public Class MyBackgroundJob
	Public Sub ProcessJob()
		' Background job logic, can be a recurring job or multiple jobs
		Console.WriteLine("Background job is running...")
	End Sub
End Class
$vbLabelText   $csharpLabel

Enqueue Jobs

Enqueue background jobs using the Hangfire API. You can schedule background jobs to run at a specific time, after a delay, or regularly.

// Enqueue a job to run immediately
BackgroundJob.Enqueue<MyBackgroundJob>(x => x.ProcessJob());

// Schedule a job to run after a 5-minute delay
BackgroundJob.Schedule<MyBackgroundJob>(x => x.ProcessJob(), TimeSpan.FromMinutes(5));

// Schedule a recurring job using a job ID
RecurringJob.AddOrUpdate<MyBackgroundJob>("jobId", x => x.ProcessJob(), Cron.Daily);
// Enqueue a job to run immediately
BackgroundJob.Enqueue<MyBackgroundJob>(x => x.ProcessJob());

// Schedule a job to run after a 5-minute delay
BackgroundJob.Schedule<MyBackgroundJob>(x => x.ProcessJob(), TimeSpan.FromMinutes(5));

// Schedule a recurring job using a job ID
RecurringJob.AddOrUpdate<MyBackgroundJob>("jobId", x => x.ProcessJob(), Cron.Daily);
' Enqueue a job to run immediately
BackgroundJob.Enqueue(Of MyBackgroundJob)(Function(x) x.ProcessJob())

' Schedule a job to run after a 5-minute delay
BackgroundJob.Schedule(Of MyBackgroundJob)(Function(x) x.ProcessJob(), TimeSpan.FromMinutes(5))

' Schedule a recurring job using a job ID
RecurringJob.AddOrUpdate(Of MyBackgroundJob)("jobId", Function(x) x.ProcessJob(), Cron.Daily)
$vbLabelText   $csharpLabel

Hangfire Dashboard and Server

The Hangfire dashboard and server can be added in the Configure method for real-time job monitoring.

// Run Hangfire server and dashboard
app.UseHangfireServer();
app.UseHangfireDashboard();
// Run Hangfire server and dashboard
app.UseHangfireServer();
app.UseHangfireDashboard();
' Run Hangfire server and dashboard
app.UseHangfireServer()
app.UseHangfireDashboard()
$vbLabelText   $csharpLabel

The server can also be added in ConfigureServices.

services.AddHangfireServer();
services.AddHangfireServer();
services.AddHangfireServer()
$vbLabelText   $csharpLabel

Fire and Forget Jobs

// Fire and forget jobs are executed only once and almost immediately after creation.
var jobId = BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget!")); // Job ID for fire and forget job
// Fire and forget jobs are executed only once and almost immediately after creation.
var jobId = BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget!")); // Job ID for fire and forget job
' Fire and forget jobs are executed only once and almost immediately after creation.
Dim jobId = BackgroundJob.Enqueue(Sub() Console.WriteLine("Fire-and-forget!")) ' Job ID for fire and forget job
$vbLabelText   $csharpLabel

Recurring Jobs

// Recurring jobs fire many times based on a specified CRON schedule.
RecurringJob.AddOrUpdate("myrecurringjob", () => Console.WriteLine("Recurring!"), Cron.Daily);
// Recurring jobs fire many times based on a specified CRON schedule.
RecurringJob.AddOrUpdate("myrecurringjob", () => Console.WriteLine("Recurring!"), Cron.Daily);
' Recurring jobs fire many times based on a specified CRON schedule.
RecurringJob.AddOrUpdate("myrecurringjob", Sub() Console.WriteLine("Recurring!"), Cron.Daily)
$vbLabelText   $csharpLabel

Delayed Jobs

// Delayed jobs are executed only once but after a specified interval.
var jobId = BackgroundJob.Schedule(() => Console.WriteLine("Delayed!"), TimeSpan.FromDays(7));
// Delayed jobs are executed only once but after a specified interval.
var jobId = BackgroundJob.Schedule(() => Console.WriteLine("Delayed!"), TimeSpan.FromDays(7));
' Delayed jobs are executed only once but after a specified interval.
Dim jobId = BackgroundJob.Schedule(Sub() Console.WriteLine("Delayed!"), TimeSpan.FromDays(7))
$vbLabelText   $csharpLabel

Continuations

// Continuation jobs are executed once their parent jobs have completed.
BackgroundJob.ContinueJobWith(jobId, () => Console.WriteLine("Continuation!"));
// Continuation jobs are executed once their parent jobs have completed.
BackgroundJob.ContinueJobWith(jobId, () => Console.WriteLine("Continuation!"));
' Continuation jobs are executed once their parent jobs have completed.
BackgroundJob.ContinueJobWith(jobId, Sub() Console.WriteLine("Continuation!"))
$vbLabelText   $csharpLabel

Batch Job

// Batch is a group of background jobs created atomically and considered as a single entity.
var batchId = BatchJob.StartNew(x =>
{
    x.Enqueue(() => Console.WriteLine("Job 1"));
    x.Enqueue(() => Console.WriteLine("Job 2"));
});
// Batch is a group of background jobs created atomically and considered as a single entity.
var batchId = BatchJob.StartNew(x =>
{
    x.Enqueue(() => Console.WriteLine("Job 1"));
    x.Enqueue(() => Console.WriteLine("Job 2"));
});
' Batch is a group of background jobs created atomically and considered as a single entity.
Dim batchId = BatchJob.StartNew(Sub(x)
	x.Enqueue(Sub() Console.WriteLine("Job 1"))
	x.Enqueue(Sub() Console.WriteLine("Job 2"))
End Sub)
$vbLabelText   $csharpLabel

Batch Continuation Job

// Batch continuation is fired when all background jobs in a parent batch are finished.
BatchJob.ContinueBatchWith(batchId, x =>
{
    x.Enqueue(() => Console.WriteLine("Last Job"));
});
// Batch continuation is fired when all background jobs in a parent batch are finished.
BatchJob.ContinueBatchWith(batchId, x =>
{
    x.Enqueue(() => Console.WriteLine("Last Job"));
});
' Batch continuation is fired when all background jobs in a parent batch are finished.
BatchJob.ContinueBatchWith(batchId, Sub(x)
	x.Enqueue(Sub() Console.WriteLine("Last Job"))
End Sub)
$vbLabelText   $csharpLabel

Dashboard

Hangfire Dashboard is where you can find all information about your background jobs. It is written as an OWIN middleware (if you are not familiar with OWIN, don’t worry), so you can plug it into your ASP.NET, ASP.NET MVC, Nancy, and ServiceStack applications, as well as use the OWIN Self-Host feature to host Dashboard inside Console Applications or Windows Services.

When you have the dashboard enabled, it is available at the /hangfire/ extension. In this dashboard, you can manage background running jobs, schedule background jobs, and view fire and forget jobs along with recurring jobs. The jobs can be identified using a job ID.

Live processing

Hangfire .NET Core (How It Works For Developer): Figure 3 - Live Processing of Jobs

Succeeded Jobs

View successful jobs below.

Hangfire .NET Core (How It Works For Developer): Figure 4 - Succeeded Jobs

Scheduled jobs

Hangfire .NET Core (How It Works For Developer): Figure 5 - Scheduled Jobs

When your application runs, Hangfire will take care of processing the background jobs based on the configured settings.

Remember to check the Hangfire documentation for more advanced configuration options and features: Hangfire Documentation and complete code can be found on GitHub Hangfire Demo.

Introducing IronPDF

IronPDF for .NET PDF Generation is a NuGet package from Iron Software's PDF Library that helps to read and generate PDF docs. It can convert easily formatted documents with style information to PDF. IronPDF can easily generate PDFs from HTML content. It can download the HTML from the URL and then generate PDFs.

The main attraction of IronPDF is its HTML to PDF Conversion function, which preserves layouts and styles. It can create PDFs from web content, ideal for reports, invoices, and documentation. This feature supports converting HTML files, URLs, and HTML strings to PDFs.

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
Imports IronPdf

Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim renderer = New ChromePdfRenderer()

		' Convert HTML String to PDF
		Dim htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>"
		Dim pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent)
		pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf")

		' Convert HTML File to PDF
		Dim htmlFilePath = "path_to_your_html_file.html" ' Specify the path to your HTML file
		Dim pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath)
		pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf")

		' Convert URL to PDF
		Dim url = "http://ironpdf.com" ' Specify the URL
		Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
		pdfFromUrl.SaveAs("URLToPDF.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

Get started with IronPDF

Install IronPDF Library

Install Using NuGet Package Manager

To integrate IronPDF into your Hangfire .NET project using the NuGet Package Manager, follow these steps:

  1. Open Visual Studio and in the Solution Explorer, right-click on your project.
  2. Choose “Manage NuGet Packages…” from the context menu.
  3. Go to the Browse tab and search for IronPDF.
  4. Select the IronPDF library from the search results and click the Install button.
  5. Accept any license agreement prompt.

If you prefer using the Package Manager Console, execute the following command:

Install-Package IronPdf

This will fetch and install IronPDF into your project.

Install Using NuGet Website

For a detailed overview of IronPDF, including features, compatibility, and additional download options, visit the IronPDF page on the NuGet website at https://www.nuget.org/packages/IronPdf.

Install Via DLL

Alternatively, you can incorporate IronPDF directly into your project using its DLL file. Download the ZIP file containing the DLL from this IronPDF Direct Download. Unzip it, and include the DLL in your project.

Now let's modify our application to add a background processing job to download a website as a PDF file.

namespace HangfireDemo.Core;

public class PdfGenerationJob
{
    public void Start(string website)
    {
        // Create a PDF from any existing web page
        ChromePdfRenderer renderer = new ChromePdfRenderer();
        PdfDocument pdf = renderer.RenderUrlAsPdf(website);
        var filePath = AppContext.BaseDirectory + "result.pdf";
        pdf.SaveAs(filePath);
    }
}
namespace HangfireDemo.Core;

public class PdfGenerationJob
{
    public void Start(string website)
    {
        // Create a PDF from any existing web page
        ChromePdfRenderer renderer = new ChromePdfRenderer();
        PdfDocument pdf = renderer.RenderUrlAsPdf(website);
        var filePath = AppContext.BaseDirectory + "result.pdf";
        pdf.SaveAs(filePath);
    }
}
Namespace HangfireDemo.Core

	Public Class PdfGenerationJob
		Public Sub Start(ByVal website As String)
			' Create a PDF from any existing web page
			Dim renderer As New ChromePdfRenderer()
			Dim pdf As PdfDocument = renderer.RenderUrlAsPdf(website)
			Dim filePath = AppContext.BaseDirectory & "result.pdf"
			pdf.SaveAs(filePath)
		End Sub
	End Class
End Namespace
$vbLabelText   $csharpLabel

IronPDF has an inbuilt method to download a website from a URL and save it as a PDF document. We are going to use this method in our job to download and save it to a specified location. This background job can be modified to take multiple website URLs and save them as PDFs.

Now, let's add a controller to expose the PDF generation and download APIs.

using Hangfire;
using HangfireDemo.Core;
using Microsoft.AspNetCore.Mvc;

namespace HangfireDemo.Controllers;

[ApiController]
[Route("[controller]")]
public class PdfGeneratorController : ControllerBase
{
    [HttpGet("request", Name = "Start PDF Generation")]
    public void Start([FromQuery] string websiteUrl)
    {
        BackgroundJob.Enqueue<PdfGenerationJob>(x => x.Start(websiteUrl));
    }

    [HttpGet("result", Name = "Download PDF Generation")]
    public IActionResult WebResult()
    {
        var filePath = AppContext.BaseDirectory + "result.pdf";
        var stream = new FileStream(filePath, FileMode.Open);
        return new FileStreamResult(stream, "application/octet-stream") { FileDownloadName = "website.pdf" };
    }
}
using Hangfire;
using HangfireDemo.Core;
using Microsoft.AspNetCore.Mvc;

namespace HangfireDemo.Controllers;

[ApiController]
[Route("[controller]")]
public class PdfGeneratorController : ControllerBase
{
    [HttpGet("request", Name = "Start PDF Generation")]
    public void Start([FromQuery] string websiteUrl)
    {
        BackgroundJob.Enqueue<PdfGenerationJob>(x => x.Start(websiteUrl));
    }

    [HttpGet("result", Name = "Download PDF Generation")]
    public IActionResult WebResult()
    {
        var filePath = AppContext.BaseDirectory + "result.pdf";
        var stream = new FileStream(filePath, FileMode.Open);
        return new FileStreamResult(stream, "application/octet-stream") { FileDownloadName = "website.pdf" };
    }
}
Imports Hangfire
Imports HangfireDemo.Core
Imports Microsoft.AspNetCore.Mvc

Namespace HangfireDemo.Controllers

	<ApiController>
	<Route("[controller]")>
	Public Class PdfGeneratorController
		Inherits ControllerBase

		<HttpGet("request", Name := "Start PDF Generation")>
		Public Sub Start(<FromQuery> ByVal websiteUrl As String)
			BackgroundJob.Enqueue(Of PdfGenerationJob)(Function(x) x.Start(websiteUrl))
		End Sub

		<HttpGet("result", Name := "Download PDF Generation")>
		Public Function WebResult() As IActionResult
			Dim filePath = AppContext.BaseDirectory & "result.pdf"
			Dim stream = New FileStream(filePath, FileMode.Open)
			Return New FileStreamResult(stream, "application/octet-stream") With {.FileDownloadName = "website.pdf"}
		End Function
	End Class
End Namespace
$vbLabelText   $csharpLabel

Here we have created two APIs: one to start the background job and take the website URL for initiating the download, and another API to download the resulting PDF. The APIs are depicted as shown below.

Hangfire .NET Core (How It Works For Developer): Figure 7 - PDFGenerator APIs

And the result looks like this:

Hangfire .NET Core (How It Works For Developer): Figure 8 - Output

Licensing (Free Trial Available)

For the above code to work without watermarks, a license key is required. A trial license is available for developers upon registering with IronPDF Free Trial. No credit card is required for a trial license. You can provide your email ID and register for a free trial.

Conclusion

Hangfire and IronPDF together are a great combination for generating and downloading PDFs in the background. Hangfire enables efficient processing of long-running tasks, while IronPDF provides a flexible and easy-to-use solution for PDF generation. To learn more about IronPDF, you can visit the IronPDF Documentation.

Also, explore other tools from the Iron Software Product Suite which can enhance your coding skills and meet modern application requirements.

Frequently Asked Questions

What is Hangfire in .NET Core?

Hangfire is a framework that simplifies the implementation of background processing in ASP.NET Core or .NET Core 6 applications. It provides a reliable and flexible solution for managing and executing background jobs.

How do I install Hangfire in a .NET Core application?

Hangfire can be installed as a NuGet package. You can add it using the .NET CLI with the command: 'dotnet add package Hangfire --version 1.8.6'.

What are the types of background jobs Hangfire supports?

Hangfire supports various types of background jobs including Fire-and-forget jobs, Delayed jobs, Recurring jobs, and Continuation jobs.

How do you configure Hangfire in a .NET Core application?

Hangfire is configured in the Startup.cs file where you set up job storage and initialize the Hangfire server. It usually involves adding Hangfire services and setting up a SQL Server or in-memory storage.

What is the Hangfire Dashboard?

The Hangfire Dashboard is a tool for monitoring and managing background jobs. It provides information about live processing, succeeded jobs, and scheduled jobs, and is accessible through a web interface.

How can you create a background job using Hangfire?

Background jobs can be created using Hangfire by defining the methods you want to run as jobs and then enqueuing them using the Hangfire API. Jobs can be scheduled to run immediately, after a delay, or on a recurring basis.

How can you perform PDF generation tasks in the background?

You can perform PDF generation tasks in the background by using a PDF library that supports HTML to PDF conversion. This can be integrated into a background job processing framework to automate PDF creation from HTML content.

What are some capabilities of a PDF generation library?

A PDF generation library can convert HTML strings, HTML files, and URLs to PDFs. It preserves layouts and styles and is useful for generating reports, invoices, and documentation from web content.

How can you install a PDF generation library in a .NET project?

A PDF generation library can be installed using the NuGet Package Manager in Visual Studio or via the Package Manager Console with a specific command. It can also be installed by downloading the DLL directly from the library's website.

What is required for using a PDF generation library without watermarks?

To use a PDF generation library without watermarks, a license key is usually required. A free trial license may be available upon registering on the library's website.

Chipego
Software Engineer
Chipego has a natural skill for listening that helps him to comprehend customer issues, and offer intelligent solutions. He joined the Iron Software team in 2023, after studying a Bachelor of Science in Information Technology. IronPDF and IronOCR are the two products Chipego has been focusing on, but his knowledge of all products is growing daily, as he finds new ways to support customers. He enjoys how collaborative life is at Iron Software, with team members from across the company bringing their varied experience to contribute to effective, innovative solutions. When Chipego is away from his desk, he can often be found enjoying a good book or playing football.