Pruebas en un entorno real
Pruebe en producción sin marcas de agua.
Funciona donde lo necesites.
El desarrollo de aplicaciones modernas a menudo requiere procesar tareas en segundo plano para gestionar tareas de gran envergadura, en este escenario necesitamos gestores de tareas en segundo plano para ejecutar múltiples tareas. Hay muchos gestores de trabajos, y uno de esos gestores de trabajos padre en segundo plano para aplicaciones C# .NET Core es Hangfire. En este blog, vamos a aprender sobre el trabajo en segundo plano Hangfire y cómo usarlo con otros paquetes como IronPDF para generar documentos PDF en segundo plano.
Hangfire simplifica la implementación del procesamiento en segundo plano en aplicaciones ASP.NET Core o .NET Core 6 Web API al proporcionar un marco fiable y flexible para gestionar y ejecutar trabajos en segundo plano. Hangfire está disponible como NuGet y puede instalarse utilizando .NET CLI como se indica a continuación.
dotnet add package Hangfire --version 1.8.6
Para aprender sobre Hangfire, vamos a crear una simple aplicación .NET Core API e instalar Hangfire usando CLI.
dotnet new webapi -n HangfireDemo
cd HangfireDemo
dotnet build
dotnet add package Hangfire --version 1.8.6
dotnet build
Aquí estamos creando una simple API REST meteorológica usando .NET CLI. La primera línea crea un proyecto Core Web API llamado HangfireDemo (también puede crear ASP.NET Core) para ejecutar los puntos finales de la API. La segunda línea es para navegar a nuestra carpeta recién creada "HangfireDemo" y luego construir el proyecto. A continuación, añadimos el paquete NuGet de Hangfire a nuestro proyecto y volvemos a compilarlo. Después de esto, puede abrir su proyecto en cualquier editor de su elección, Visual Studio 2022 o JetBrains Rider. Ahora si ejecutas el proyecto puedes ver el Swagger como abajo.
Aquí podemos ver las API GET meteorológicas que devuelven la fecha, el resumen y la temperatura.
Ahora vamos a añadir un procesador de trabajos en segundo plano Hangfire. Abra el proyecto en Visual Studio.
Configure Hangfire en su aplicación, normalmente en el archivo Startup.cs. Esto implica configurar un almacenamiento de trabajos e inicializar el servidor Hangfire.
// Startup.cs
using Hangfire;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Add Hangfire services
services.AddHangfire(config => config.UseSqlServerStorage("your_connection_string"));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Configure Hangfire
app.UseHangfireServer();
app.UseHangfireDashboard();
// Your other configuration settings
}
}
// Startup.cs
using Hangfire;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Add Hangfire services
services.AddHangfire(config => config.UseSqlServerStorage("your_connection_string"));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Configure Hangfire
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
services.AddHangfire(Function(config) config.UseSqlServerStorage("your_connection_string"))
End Sub
Public Sub Configure(ByVal app As IApplicationBuilder, ByVal env As IHostingEnvironment)
' Configure Hangfire
app.UseHangfireServer()
app.UseHangfireDashboard()
' Your other configuration settings
End Sub
End Class
ConfigureServices se utiliza para añadir almacenamiento para guardar los trabajos recién creados de Hangfire. Aquí se utiliza la base de datos SQL Server. La cadena de conexión de SQL Server debe sustituirse por "tu_cadena_de_conexión". También se puede utilizar el almacenamiento en memoria con Hangfire.InMemory.
dotnet add package Hangfire.InMemory --version 0.6.0
Y sustituir por
services.AddHangfire(configuration => { configuration.UseInMemoryStorage(); });
services.AddHangfire(configuration => { configuration.UseInMemoryStorage(); });
services.AddHangfire(Sub(configuration)
configuration.UseInMemoryStorage()
End Sub)
Defina los métodos que desea ejecutar como trabajo en segundo plano. Estos métodos deben ser estáticos o métodos de instancia de una clase con un constructor sin parámetros. Los trabajos pueden ejecutarse como trabajos recurrentes o pueden ejecutarse muchos trabajos.
public class MyBackgroundJob
{
public void ProcessJob()
{
// Your background job logic, recurring job or multiple jobs
Console.WriteLine("Background job is running...");
}
}
public class MyBackgroundJob
{
public void ProcessJob()
{
// Your background job logic, recurring job or multiple jobs
Console.WriteLine("Background job is running...");
}
}
Public Class MyBackgroundJob
Public Sub ProcessJob()
' Your background job logic, recurring job or multiple jobs
Console.WriteLine("Background job is running...")
End Sub
End Class
Ponga en cola trabajos en segundo plano utilizando la API de Hangfire. Puedes programar trabajos en segundo plano para que se ejecuten a una hora determinada, tras un retraso o de forma regular.
// Enqueue a job to run immediately
BackgroundJob.Enqueue<MyBackgroundJob>(x => x.ProcessJob());
// Schedule a job to run after 5 min delay, delayed job
BackgroundJob.Schedule<MyBackgroundJob>(x => x.ProcessJob(), TimeSpan.FromMinutes(5));
// Schedule a recurring job / recurring jobs using job Id
RecurringJob.AddOrUpdate<MyBackgroundJob>("job Id", x => x.ProcessJob(), Cron.Daily);
// Enqueue a job to run immediately
BackgroundJob.Enqueue<MyBackgroundJob>(x => x.ProcessJob());
// Schedule a job to run after 5 min delay, delayed job
BackgroundJob.Schedule<MyBackgroundJob>(x => x.ProcessJob(), TimeSpan.FromMinutes(5));
// Schedule a recurring job / recurring jobs using job Id
RecurringJob.AddOrUpdate<MyBackgroundJob>("job Id", 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 5 min delay, delayed job
BackgroundJob.Schedule(Of MyBackgroundJob)(Function(x) x.ProcessJob(), TimeSpan.FromMinutes(5))
' Schedule a recurring job / recurring jobs using job Id
RecurringJob.AddOrUpdate(Of MyBackgroundJob)("job Id", Function(x) x.ProcessJob(), Cron.Daily)
El cuadro de mandos y el servidor de Hangfire pueden añadirse en el método Configurar.
// Run Hangfire server
app.UseHangfireServer();
app.UseHangfireDashboard();
// Run Hangfire server
app.UseHangfireServer();
app.UseHangfireDashboard();
' Run Hangfire server
app.UseHangfireServer()
app.UseHangfireDashboard()
El servidor también puede añadirse en ConfigureServices.
services.AddHangfireServer();
services.AddHangfireServer();
services.AddHangfireServer()
//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!")); //jobId for Fire and forget job
//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!")); //jobId for Fire and forget job
'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!")) 'jobId for Fire and forget job
//Recurring jobs fire many times on the specified CRON schedule.
RecurringJob.AddOrUpdate( "myrecurringjob",() => Console.WriteLine("Recurring!"),Cron.Daily);
//Recurring jobs fire many times on the specified CRON schedule.
RecurringJob.AddOrUpdate( "myrecurringjob",() => Console.WriteLine("Recurring!"),Cron.Daily);
'Recurring jobs fire many times on the specified CRON schedule.
RecurringJob.AddOrUpdate("myrecurringjob",Sub() Console.WriteLine("Recurring!"),Cron.Daily)
//Delayed jobs are executed only once too, but not immediately, after a certain specific interval.
var jobId = BackgroundJob.Schedule(() => Console.WriteLine("Delayed!"),
TimeSpan.FromDays(7));
//Delayed jobs are executed only once too, but not immediately, after a certain specific interval.
var jobId = BackgroundJob.Schedule(() => Console.WriteLine("Delayed!"),
TimeSpan.FromDays(7));
'Delayed jobs are executed only once too, but not immediately, after a certain specific interval.
Dim jobId = BackgroundJob.Schedule(Sub() Console.WriteLine("Delayed!"), TimeSpan.FromDays(7))
//Continuation jobs are executed when its parent job has been finished, immediate child job
BackgroundJob.ContinueJobWith(jobId,() => Console.WriteLine("Continuation!"));
//Continuation jobs are executed when its parent job has been finished, immediate child job
BackgroundJob.ContinueJobWith(jobId,() => Console.WriteLine("Continuation!"));
'Continuation jobs are executed when its parent job has been finished, immediate child job
BackgroundJob.ContinueJobWith(jobId,Sub() Console.WriteLine("Continuation!"))
//Batch is a group of background jobs that is created atomically and considered as a single entity. Two jobs can be run as below.
var batchId = BatchJob.StartNew(x =>
{
x.Enqueue(() => Console.WriteLine("Job 1"));
x.Enqueue(() => Console.WriteLine("Job 2"));
});
//Batch is a group of background jobs that is created atomically and considered as a single entity. Two jobs can be run as below.
var batchId = BatchJob.StartNew(x =>
{
x.Enqueue(() => Console.WriteLine("Job 1"));
x.Enqueue(() => Console.WriteLine("Job 2"));
});
'Batch is a group of background jobs that is created atomically and considered as a single entity. Two jobs can be run as below.
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"));
});
Dim tempVar As Boolean = TypeOf continuation Is fired
Dim [when] As fired = If(tempVar, CType(continuation, fired), Nothing)
Batch tempVar 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 es donde puedes encontrar toda la información sobre tus trabajos de fondo. Está escrito como un middleware OWIN (si no conoce OWIN, no se preocupe)por lo que puede conectarlo a su aplicación ASP.NET, ASP.NET MVC, Nancy y ServiceStack, así como utilizar la función OWIN Autoalojamiento para alojar Dashboard dentro de Aplicaciones de Consola o en Servicios de Windows.
Cuando tienes el tablero habilitado en tu vista, el tablero está en la extensión /hangfire/. En este panel de control, se pueden gestionar los trabajos en ejecución en segundo plano, programar trabajos en segundo plano, ver los trabajos de disparar y olvidar y los trabajos recurrentes. Los trabajos pueden identificarse mediante el ID de trabajo.
Los empleos seleccionados pueden consultarse a continuación.
Ahora, cuando su aplicación se ejecute, Hangfire se encargará de procesar los trabajos en segundo plano basándose en los ajustes configurados.
No olvide consultar la documentación de Hangfire para conocer opciones de configuración y características más avanzadas: Hangfire Documentación y el código completo en GitHub.
IronPDF es un NuGet paquete de Iron Software que ayuda a leer y generar documentos PDF. Puede convertir fácilmente documentos formateados con información de estilo a PDF. IronPDF puede generar fácilmente archivos PDF a partir de contenido HTML. Puede descargar el HTML de la URL y luego generar los PDF.
El principal atractivo de IronPDF es su HTML a PDF que conserva los diseños y estilos. Puede crear PDF a partir de contenido web, ideal para informes, facturas y documentación. Esta función permite convertir archivos HTML, URL y cadenas HTML en PDF.
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
// 1. 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");
// 2. 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");
// 3. 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();
// 1. 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");
// 2. 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");
// 3. 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()
' 1. 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")
' 2. 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")
' 3. 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
Install-Package IronPdf
Para integrar IronPDF en su proyecto Hangfire .NET utilizando el gestor de paquetes NuGet, siga estos pasos:
Acepte cualquier solicitud de acuerdo de licencia.
Si desea incluir IronPDF en su proyecto a través de la consola del gestor de paquetes, ejecute el siguiente comando en la consola del gestor de paquetes:
Install-Package IronPdf
Buscará e instalará IronPDF en su proyecto.
Para obtener una descripción detallada de IronPDF, incluidas sus características, compatibilidad y opciones de descarga adicionales, visite la página de IronPDF en el sitio web de NuGet en https://www.nuget.org/packages/IronPdf.
Como alternativa, puede incorporar IronPDF directamente a su proyecto utilizando su archivo dll. Descargue el archivo ZIP que contiene la DLL desde aquí enlace. Descomprímelo e incluye la DLL en tu proyecto.
Ahora vamos a modificar nuestra aplicación para añadir un trabajo de procesamiento en segundo plano para descargar un sitio web de canalización de peticiones HTTP como un archivo PDF.
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 tiene un método incorporado para descargar un sitio web desde una URL y guardarlo como documento PDF. Vamos a utilizar este método en nuestro trabajo para descargarlo y guardarlo en una ubicación temporal. Esta tarea en segundo plano puede modificarse para tomar varias URL de sitios web y guardarlas como PDF.
Ahora vamos a añadir un controlador para exponer las API de generación y descarga de 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" };
}
}
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
Aquí hemos creado dos APIs, una para iniciar el trabajo en segundo plano para tomar la URL del sitio web e iniciar la descarga. Otra API consiste en descargar el resultado en PDF. Las API tienen el aspecto que se muestra a continuación.
El resultado es el siguiente.
Para que el código anterior funcione sin marca de agua, se necesita una clave de licencia. Los desarrolladores disponen de una licencia de prueba para registrarse. aquí y sí, no se requiere tarjeta de crédito para una licencia de prueba. Uno puede proporcionar el ID de correo electrónico y registrarse para una prueba gratuita.
Hangfire e IronPDF juntos son una gran combinación para generar y descargar PDFs en segundo plano. Podemos utilizar Hangfire en varios paradigmas de programación para procesar tareas de larga duración. IronPDF ofrece una solución flexible y fácil de usar para generar archivos PDF. Para saber más sobre IronPDF, puede consultar los documentos aquí.
También puede explorar otras herramientas de Iron Software que le ayudará a mejorar sus habilidades de codificación y a cumplir los requisitos de las aplicaciones modernas.
9 productos API .NET para sus documentos de oficina