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.
// Inicio.cs
using Hangfire;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Añadir servicios Hangfire
services.AddHangfire(config => config.UseSqlServerStorage("your_connection_string"));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Configurar Hangfire
app.UseHangfireServer();
app.UseHangfireDashboard();
// Otros ajustes de configuración
}
}
// Inicio.cs
using Hangfire;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Añadir servicios Hangfire
services.AddHangfire(config => config.UseSqlServerStorage("your_connection_string"));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Configurar Hangfire
app.UseHangfireServer();
app.UseHangfireDashboard();
// Otros ajustes de configuración
}
}
' Inicio.cs
Imports Hangfire
Public Class Startup
Public Sub ConfigureServices(ByVal services As IServiceCollection)
' Añadir servicios Hangfire
services.AddHangfire(Function(config) config.UseSqlServerStorage("your_connection_string"))
End Sub
Public Sub Configure(ByVal app As IApplicationBuilder, ByVal env As IHostingEnvironment)
' Configurar Hangfire
app.UseHangfireServer()
app.UseHangfireDashboard()
' Otros ajustes de configuración
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()
{
// Su lógica de trabajo de fondo, trabajo recurrente o múltiples trabajos
Console.WriteLine("Background job is running...");
}
}
public class MyBackgroundJob
{
public void ProcessJob()
{
// Su lógica de trabajo de fondo, trabajo recurrente o múltiples trabajos
Console.WriteLine("Background job is running...");
}
}
Public Class MyBackgroundJob
Public Sub ProcessJob()
' Su lógica de trabajo de fondo, trabajo recurrente o múltiples trabajos
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.
// Poner en cola un trabajo para que se ejecute inmediatamente
BackgroundJob.Enqueue<MyBackgroundJob>(x => x.ProcessJob());
// Programar un trabajo para que se ejecute con 5 minutos de retraso, trabajo retrasado
BackgroundJob.Schedule<MyBackgroundJob>(x => x.ProcessJob(), TimeSpan.FromMinutes(5));
// Programar un trabajo recurrente / trabajos recurrentes utilizando el Id de trabajo
RecurringJob.AddOrUpdate<MyBackgroundJob>("job Id", x => x.ProcessJob(), Cron.Daily);
// Poner en cola un trabajo para que se ejecute inmediatamente
BackgroundJob.Enqueue<MyBackgroundJob>(x => x.ProcessJob());
// Programar un trabajo para que se ejecute con 5 minutos de retraso, trabajo retrasado
BackgroundJob.Schedule<MyBackgroundJob>(x => x.ProcessJob(), TimeSpan.FromMinutes(5));
// Programar un trabajo recurrente / trabajos recurrentes utilizando el Id de trabajo
RecurringJob.AddOrUpdate<MyBackgroundJob>("job Id", x => x.ProcessJob(), Cron.Daily);
' Poner en cola un trabajo para que se ejecute inmediatamente
BackgroundJob.Enqueue(Of MyBackgroundJob)(Function(x) x.ProcessJob())
' Programar un trabajo para que se ejecute con 5 minutos de retraso, trabajo retrasado
BackgroundJob.Schedule(Of MyBackgroundJob)(Function(x) x.ProcessJob(), TimeSpan.FromMinutes(5))
' Programar un trabajo recurrente / trabajos recurrentes utilizando el Id de trabajo
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.
// Ejecutar el servidor Hangfire
app.UseHangfireServer();
app.UseHangfireDashboard();
// Ejecutar el servidor Hangfire
app.UseHangfireServer();
app.UseHangfireDashboard();
' Ejecutar el servidor Hangfire
app.UseHangfireServer()
app.UseHangfireDashboard()
El servidor también puede añadirse en ConfigureServices.
services.AddHangfireServer();
services.AddHangfireServer();
services.AddHangfireServer()
//Fire and forget job / Los trabajos Fire and forget se ejecutan una sola vez y casi inmediatamente después de su creación.
var jobId = BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget!")); //jobId para Fire and forget job
//Fire and forget job / Los trabajos Fire and forget se ejecutan una sola vez y casi inmediatamente después de su creación.
var jobId = BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget!")); //jobId para Fire and forget job
'Fire and forget job / Los trabajos Fire and forget se ejecutan una sola vez y casi inmediatamente después de su creación.
Dim jobId = BackgroundJob.Enqueue(Sub() Console.WriteLine("Fire-and-forget!")) 'jobId para Fire and forget job
//Los trabajos recurrentes se disparan muchas veces en el horario CRON especificado.
RecurringJob.AddOrUpdate( "myrecurringjob",() => Console.WriteLine("Recurring!"),Cron.Daily);
//Los trabajos recurrentes se disparan muchas veces en el horario CRON especificado.
RecurringJob.AddOrUpdate( "myrecurringjob",() => Console.WriteLine("Recurring!"),Cron.Daily);
'Los trabajos recurrentes se disparan muchas veces en el horario CRON especificado.
RecurringJob.AddOrUpdate("myrecurringjob",Sub() Console.WriteLine("Recurring!"),Cron.Daily)
//Los trabajos retrasados también se ejecutan una sola vez, pero no inmediatamente, tras un intervalo determinado.
var jobId = BackgroundJob.Schedule(() => Console.WriteLine("Delayed!"),
TimeSpan.FromDays(7));
//Los trabajos retrasados también se ejecutan una sola vez, pero no inmediatamente, tras un intervalo determinado.
var jobId = BackgroundJob.Schedule(() => Console.WriteLine("Delayed!"),
TimeSpan.FromDays(7));
'Los trabajos retrasados también se ejecutan una sola vez, pero no inmediatamente, tras un intervalo determinado.
Dim jobId = BackgroundJob.Schedule(Sub() Console.WriteLine("Delayed!"), TimeSpan.FromDays(7))
//Los trabajos de continuación se ejecutan cuando su trabajo padre ha finalizado, trabajo hijo inmediato
BackgroundJob.ContinueJobWith(jobId,() => Console.WriteLine("Continuation!"));
//Los trabajos de continuación se ejecutan cuando su trabajo padre ha finalizado, trabajo hijo inmediato
BackgroundJob.ContinueJobWith(jobId,() => Console.WriteLine("Continuation!"));
'Los trabajos de continuación se ejecutan cuando su trabajo padre ha finalizado, trabajo hijo inmediato
BackgroundJob.ContinueJobWith(jobId,Sub() Console.WriteLine("Continuation!"))
//Lote es un grupo de trabajos en segundo plano que se crea atómicamente y se considera como una sola entidad. Dos trabajos pueden ejecutarse como se indica a continuación.
var batchId = BatchJob.StartNew(x =>
{
x.Enqueue(() => Console.WriteLine("Job 1"));
x.Enqueue(() => Console.WriteLine("Job 2"));
});
//Lote es un grupo de trabajos en segundo plano que se crea atómicamente y se considera como una sola entidad. Dos trabajos pueden ejecutarse como se indica a continuación.
var batchId = BatchJob.StartNew(x =>
{
x.Enqueue(() => Console.WriteLine("Job 1"));
x.Enqueue(() => Console.WriteLine("Job 2"));
});
'Lote es un grupo de trabajos en segundo plano que se crea atómicamente y se considera como una sola entidad. Dos trabajos pueden ejecutarse como se indica a continuación.
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.
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)
{
// Crear un PDF a partir de cualquier página web existente
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)
{
// Crear un PDF a partir de cualquier página web existente
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)
' Crear un PDF a partir de cualquier página web existente
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