Test in production without watermarks.
Works wherever you need it to.
Get 30 days of fully functional product.
Have it up and running in minutes.
Full access to our support engineering team during your product trial
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
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
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:
Here we can see the weather GET APIs, which return date, summary, and temperature.
Now let us add a Hangfire background job processor. Open the project in Visual Studio.
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
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)
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
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)
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()
The server can also be added in ConfigureServices
.
services.AddHangfireServer();
services.AddHangfireServer();
services.AddHangfireServer()
// 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
// 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)
// 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))
// 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!"))
// 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)
// 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)
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.
View successful jobs below.
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.
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
To integrate IronPDF into your Hangfire .NET project using the NuGet Package Manager, follow these steps:
If you prefer using the Package Manager Console, execute the following command:
Install-Package IronPdf
This will fetch and install IronPDF into your project.
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.
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
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
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.
And the result looks like this:
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.
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.
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.
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'.
Hangfire supports various types of background jobs including Fire-and-forget jobs, Delayed jobs, Recurring jobs, and Continuation jobs.
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.
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.
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.
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.
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.
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.
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.