Saltar al pie de página
.NET AYUDA

C# BackgroundWorker (Cómo Funciona para Desarrolladores)

Generar PDFs con IronPDF es una tarea común para los desarrolladores de .NET, especialmente cuando se crean informes dinámicos, facturas o sistemas de automatización de documentos. Pero si alguna vez has desencadenado la generación de PDFs en el hilo principal de la interfaz de usuario en una aplicación de Windows Forms o WPF, probablemente hayas visto que tu interfaz de usuario se congela o se vuelve no respondente. Esto es especialmente cierto cuando se renderiza contenido HTML grande o se procesan diseños de PDF complejos.

Ahí es donde entra en juego la clase C# BackgroundWorker. Este artículo explica cómo integrar IronPDF con BackgroundWorker para manejar operaciones asincrónicas en una aplicación de escritorio sin bloquear la interfaz de usuario.

¿Por qué utilizar BackgroundWorker con IronPDF?

Mantenga su interfaz de usuario receptiva

Cuando ejecutas tareas intensivas de CPU o de E/S como la generación de PDFs en el hilo principal, bloquea la UI. Los usuarios no pueden hacer clic, arrastrar o interactuar con la aplicación mientras está ocupada. Al usar un objeto BackgroundWorker, puedes mover el trabajo a un hilo separado, manteniendo tu interfaz ágil y utilizable durante el procesamiento en segundo plano.

Perfecto para la generación de informes y tareas de larga duración

Si tu aplicación implica exportar datos, convertir HTML a PDF o generar informes detallados, delegar eso a un trabajador en segundo plano hace que tu aplicación sea más profesional y eficiente.

Compatible con aplicaciones WinForms heredadas

Aunque las aplicaciones modernas a menudo usan async/await, muchos proyectos antiguos aún se benefician de BackgroundWorker por su simplicidad y soporte en tiempo de diseño en Visual Studio.

¿Qué es IronPDF?

C# BackgroundWorker (Cómo Funciona para Desarrolladores): Figura 1 - IronPDF

IronPDF es una potente biblioteca .NET diseñada para generar, editar y trabajar con documentos PDF en C#. Utiliza un navegador Chromium sin cabeza, permitiendo a los desarrolladores convertir HTML, CSS, JavaScript, e incluso páginas web complejas en PDFs precisos de calidad de impresión. A diferencia de los generadores de PDFs tradicionales, IronPDF renderiza documentos exactamente como aparecerían en un navegador, igualando diseño, fuentes, imágenes y estilos píxel por píxel.

Características Clave

  • Conversión de HTML a PDF – Renderiza cadenas HTML, URLs o páginas web completas en PDFs.
  • Renderizado de Imágenes y Texto – Agrega encabezados, pies de página, marcas de agua e imágenes programáticamente.
  • Combinación y División de PDFs – Combina varios documentos o extrae páginas específicas.
  • Relleno de Formularios y Anotaciones – Trabaja con formularios PDF interactivos.
  • Sin Dependencias Externas – Funciona sin necesidad de tener instalado Adobe Acrobat o Microsoft Office.

IronPDF es compatible con .NET Framework, .NET Core y .NET 6/7+, lo que lo hace ideal para aplicaciones .NET tanto de escritorio como basadas en la web.

Instalación de IronPDF a través de NuGet

Para comenzar, instala IronPDF en tu proyecto usando NuGet Package Manager:

Install-Package IronPdf

Esto añadirá todas las referencias necesarias para que puedas comenzar a usar el ChromePdfRenderer, HtmlToPdf y otras potentes características de IronPDF.

Para este ejemplo, usaremos una aplicación de Windows Forms creada con Visual Studio, con un botón que desencadena la generación del PDF y una etiqueta para indicar cuando el proceso haya concluido.

Implementación de BackgroundWorker para IronPDF

Ahora, utilizaremos los siguientes ejemplos de código para descomponer el proceso de uso de BackgroundWorker de manera estructurada y segura:

Paso 1 - Definir el BackgroundWorker

Puedes crear y configurar un BackgroundWorker ya sea en el diseñador o en el código. Aquí está el enfoque de código:

private void SetupBackgroundWorker()
{
    // new backgroundworker worker instance
    worker = new BackgroundWorker(); // dowork event handler
    worker.DoWork += PdfWorker_DoWork;
    worker.RunWorkerCompleted += PdfWorker_RunWorkerCompleted; // final result handler
}
private void SetupBackgroundWorker()
{
    // new backgroundworker worker instance
    worker = new BackgroundWorker(); // dowork event handler
    worker.DoWork += PdfWorker_DoWork;
    worker.RunWorkerCompleted += PdfWorker_RunWorkerCompleted; // final result handler
}
Private Sub SetupBackgroundWorker()
	' new backgroundworker worker instance
	worker = New BackgroundWorker() ' dowork event handler
	worker.DoWork += PdfWorker_DoWork
	worker.RunWorkerCompleted += PdfWorker_RunWorkerCompleted ' final result handler
End Sub
$vbLabelText   $csharpLabel

Esto inicializa el trabajador y conecta los eventos necesarios para la ejecución y finalización en segundo plano.

Paso 2 - Manejar el evento DoWork

El método DoWork se ejecuta en un hilo diferente, realizando la operación en segundo plano (generando el PDF):

private void PdfWorker_DoWork(object sender, DoWorkEventArgs e)
{
    var Renderer = new ChromePdfRenderer();
    // Simulate input from UI or parameters
    string htmlContent = "<h1>Monthly Report</h1><p>Generated with IronPDF.</p>";
    string outputPath = Path.Combine(Environment.CurrentDirectory, "Report.pdf");
    // Generate PDF
    var pdf = Renderer.RenderHtmlAsPdf(htmlContent);
    pdf.SaveAs(outputPath);
    // Optionally pass result info
    e.Result = outputPath; // pass value to RunWorkerCompleted
}
private void PdfWorker_DoWork(object sender, DoWorkEventArgs e)
{
    var Renderer = new ChromePdfRenderer();
    // Simulate input from UI or parameters
    string htmlContent = "<h1>Monthly Report</h1><p>Generated with IronPDF.</p>";
    string outputPath = Path.Combine(Environment.CurrentDirectory, "Report.pdf");
    // Generate PDF
    var pdf = Renderer.RenderHtmlAsPdf(htmlContent);
    pdf.SaveAs(outputPath);
    // Optionally pass result info
    e.Result = outputPath; // pass value to RunWorkerCompleted
}
Private Sub PdfWorker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
	Dim Renderer = New ChromePdfRenderer()
	' Simulate input from UI or parameters
	Dim htmlContent As String = "<h1>Monthly Report</h1><p>Generated with IronPDF.</p>"
	Dim outputPath As String = Path.Combine(Environment.CurrentDirectory, "Report.pdf")
	' Generate PDF
	Dim pdf = Renderer.RenderHtmlAsPdf(htmlContent)
	pdf.SaveAs(outputPath)
	' Optionally pass result info
	e.Result = outputPath ' pass value to RunWorkerCompleted
End Sub
$vbLabelText   $csharpLabel

Nota: No puedes interactuar con los controles de la interfaz de usuario aquí ya que se ejecuta en un hilo de trabajador.

Paso 3 - Utilizar RunWorkerCompleted para notificar la finalización

Una vez que el hilo en segundo plano completa, puedes actualizar con seguridad la UI con los resultados.

private void PdfWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error != null)
    {
        MessageBox.Show("Error: " + e.Error.Message);
    }
    else
    {
        string savedPath = e.Result.ToString();
        MessageBox.Show("PDF created at:\n" + savedPath);
    }
}
private void PdfWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error != null)
    {
        MessageBox.Show("Error: " + e.Error.Message);
    }
    else
    {
        string savedPath = e.Result.ToString();
        MessageBox.Show("PDF created at:\n" + savedPath);
    }
}
Imports Microsoft.VisualBasic

Private Sub PdfWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
	If e.Error IsNot Nothing Then
		MessageBox.Show("Error: " & e.Error.Message)
	Else
		Dim savedPath As String = e.Result.ToString()
		MessageBox.Show("PDF created at:" & vbLf & savedPath)
	End If
End Sub
$vbLabelText   $csharpLabel

Paso 4 - Activación de BackgroundWorker desde la interfaz de usuario

Añade un botón de Inicio para ejecutar la tarea en segundo plano cuando se haga clic:

private void btnGeneratePDF_Click(object sender, EventArgs e)
{
    if (pdfWorker == null)
        SetupBackgroundWorker();
    if (!pdfWorker.IsBusy)
    {
        btnGeneratePDF.Enabled = false;
        pdfWorker.RunWorkerAsync(); // execute method in background
    }
}
private void btnGeneratePDF_Click(object sender, EventArgs e)
{
    if (pdfWorker == null)
        SetupBackgroundWorker();
    if (!pdfWorker.IsBusy)
    {
        btnGeneratePDF.Enabled = false;
        pdfWorker.RunWorkerAsync(); // execute method in background
    }
}
Private Sub btnGeneratePDF_Click(ByVal sender As Object, ByVal e As EventArgs)
	If pdfWorker Is Nothing Then
		SetupBackgroundWorker()
	End If
	If Not pdfWorker.IsBusy Then
		btnGeneratePDF.Enabled = False
		pdfWorker.RunWorkerAsync() ' execute method in background
	End If
End Sub
$vbLabelText   $csharpLabel

Ejemplo de código completo

Aquí está todo unido en un fragmento de Windows Forms funcional:

using System;
using System.ComponentModel;
using IronPdf;
using System.IO;
using System.Windows.Forms;
namespace TestApp
{
    public partial class Form1 : Form
    {
        private BackgroundWorker worker;
        public Form1()
        {
            InitializeComponent();
            SetupBackgroundWorker();        }
        private void SetupBackgroundWorker()
        {
            worker = new BackgroundWorker();
            worker.DoWork += PdfWorker_DoWork;
            worker.RunWorkerCompleted += PdfWorker_RunWorkerCompleted;
        }
        private void btnGeneratePDF_Click(object sender, EventArgs e)
        {
            if (!worker.IsBusy)
            {
                btnGeneratePDF.Enabled = false;
                worker.RunWorkerAsync();
            }
        }
        private void PdfWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var Renderer = new ChromePdfRenderer();
            string htmlContent = "<h1>Report</h1><p>This PDF was generated in the background.</p>";
            string outputPath = Path.Combine(Environment.CurrentDirectory, "Report.pdf");
            var pdf = Renderer.RenderHtmlAsPdf(htmlContent);
            pdf.SaveAs(outputPath);
            e.Result = outputPath;
        }
        private void PdfWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnGeneratePDF.Enabled = true;
            if (e.Error != null)
            {
                MessageBox.Show("Failed: " + e.Error.Message);
            }
            else
            {
                MessageBox.Show("PDF created: " + e.Result.ToString());
            }
        }
        private void btnGeneratePDF_Click_1(object sender, EventArgs e)
        {
            if (!worker.IsBusy)
            {
                btnGeneratePDF.Enabled = false;
                worker.RunWorkerAsync();
            }
        }
    }
}
using System;
using System.ComponentModel;
using IronPdf;
using System.IO;
using System.Windows.Forms;
namespace TestApp
{
    public partial class Form1 : Form
    {
        private BackgroundWorker worker;
        public Form1()
        {
            InitializeComponent();
            SetupBackgroundWorker();        }
        private void SetupBackgroundWorker()
        {
            worker = new BackgroundWorker();
            worker.DoWork += PdfWorker_DoWork;
            worker.RunWorkerCompleted += PdfWorker_RunWorkerCompleted;
        }
        private void btnGeneratePDF_Click(object sender, EventArgs e)
        {
            if (!worker.IsBusy)
            {
                btnGeneratePDF.Enabled = false;
                worker.RunWorkerAsync();
            }
        }
        private void PdfWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var Renderer = new ChromePdfRenderer();
            string htmlContent = "<h1>Report</h1><p>This PDF was generated in the background.</p>";
            string outputPath = Path.Combine(Environment.CurrentDirectory, "Report.pdf");
            var pdf = Renderer.RenderHtmlAsPdf(htmlContent);
            pdf.SaveAs(outputPath);
            e.Result = outputPath;
        }
        private void PdfWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnGeneratePDF.Enabled = true;
            if (e.Error != null)
            {
                MessageBox.Show("Failed: " + e.Error.Message);
            }
            else
            {
                MessageBox.Show("PDF created: " + e.Result.ToString());
            }
        }
        private void btnGeneratePDF_Click_1(object sender, EventArgs e)
        {
            if (!worker.IsBusy)
            {
                btnGeneratePDF.Enabled = false;
                worker.RunWorkerAsync();
            }
        }
    }
}
Imports System
Imports System.ComponentModel
Imports IronPdf
Imports System.IO
Imports System.Windows.Forms
Namespace TestApp
	Partial Public Class Form1
		Inherits Form

		Private worker As BackgroundWorker
		Public Sub New()
			InitializeComponent()
			SetupBackgroundWorker()
		End Sub
		Private Sub SetupBackgroundWorker()
			worker = New BackgroundWorker()
			AddHandler worker.DoWork, AddressOf PdfWorker_DoWork
			AddHandler worker.RunWorkerCompleted, AddressOf PdfWorker_RunWorkerCompleted
		End Sub
		Private Sub btnGeneratePDF_Click(ByVal sender As Object, ByVal e As EventArgs)
			If Not worker.IsBusy Then
				btnGeneratePDF.Enabled = False
				worker.RunWorkerAsync()
			End If
		End Sub
		Private Sub PdfWorker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
			Dim Renderer = New ChromePdfRenderer()
			Dim htmlContent As String = "<h1>Report</h1><p>This PDF was generated in the background.</p>"
			Dim outputPath As String = Path.Combine(Environment.CurrentDirectory, "Report.pdf")
			Dim pdf = Renderer.RenderHtmlAsPdf(htmlContent)
			pdf.SaveAs(outputPath)
			e.Result = outputPath
		End Sub
		Private Sub PdfWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
			btnGeneratePDF.Enabled = True
			If e.Error IsNot Nothing Then
				MessageBox.Show("Failed: " & e.Error.Message)
			Else
				MessageBox.Show("PDF created: " & e.Result.ToString())
			End If
		End Sub
		Private Sub btnGeneratePDF_Click_1(ByVal sender As Object, ByVal e As EventArgs)
			If Not worker.IsBusy Then
				btnGeneratePDF.Enabled = False
				worker.RunWorkerAsync()
			End If
		End Sub
	End Class
End Namespace
$vbLabelText   $csharpLabel

Salida del Formulario

C# BackgroundWorker (Cómo Funciona para Desarrolladores): Figura 2 - Salida del formulario después de la creación del PDF

Salida del PDF

C# BackgroundWorker (Cómo Funciona para Desarrolladores): Figura 3 - Salida del PDF

Mejores prácticas

Evite el acceso a la interfaz de usuario en DoWork

El manejador del evento DoWork se ejecuta en un hilo diferente, por lo que no puedes acceder a los elementos de la UI directamente. Usa RunWorkerCompleted o llamadas a Invoke() del control para actualizaciones seguras de la UI.

Soporte de cancelación asíncrona

Si tu tarea es larga, habilita WorkerSupportsCancellation = true y monitorea CancellationPending dentro de DoWork para soportar una cancelación solicitada.

Informe de progreso de actualizaciones (opcional)

Puedes habilitar WorkerReportsProgress = true y usar el evento ProgressChanged para mostrar una barra de progreso o mensajes.

Validar el argumento de entrada

Al usar RunWorkerAsync(argument), valida el argumento en DoWork y devuelve cualquier resultado de método a través de e.Result.

Conclusión

Usar BackgroundWorker con IronPDF te permite realizar tareas pesadas de renderizado de PDFs en un hilo en segundo plano, manteniendo tu aplicación responsiva. Esto es especialmente valioso cuando se trabaja con aplicaciones WinForms o WPF que requieren actualizaciones responsivas de la UI durante tareas de larga duración como la generación de PDFs.

Al manejar el evento dowork, monitorear el resultado final y actualizar de forma segura tu interfaz de usuario en el evento runworkercompleted, aseguras que tus operaciones en segundo plano se ejecuten sin problemas.

Aunque async/await es a menudo la referencia para nuevas aplicaciones, BackgroundWorker sigue siendo una herramienta confiable para proyectos antiguos o de WinForms. Ya sea que estés exportando informes o generando documentos sobre la marcha, este enfoque te ayudará a sacar el máximo provecho de IronPDF mientras mantienes tu aplicación fluida y amigable al usuario.

¿Listo para probarlo tú mismo?

Descarga la prueba gratuita de IronPDF y comienza a construir potentes soluciones de PDF en C# hoy. La prueba te da acceso completo a las características mostradas en este artículo, sin necesidad de tarjeta de crédito.

Preguntas Frecuentes

¿Cómo puedo realizar la generación de PDF en una aplicación de Windows Forms en C# sin congelar la interfaz de usuario?

Puedes utilizar la clase BackgroundWorker de C# junto con IronPDF para realizar la generación de PDF en un hilo separado. Esto asegura que el hilo principal de la UI se mantenga responsivo durante el proceso.

¿Cuál es el papel del controlador de eventos DoWork en BackgroundWorker?

El controlador de eventos DoWork es donde ejecutas la tarea de larga duración, como la generación de PDF usando IronPDF. Se ejecuta en un hilo separado de la UI, evitando que la interfaz se congele.

¿Cómo puedo actualizar la UI con los resultados de una tarea de generación de PDF en segundo plano?

Utiliza el evento RunWorkerCompleted para actualizar la UI con los resultados de tu generación de PDF. Este evento se activa una vez que la tarea en segundo plano está completa, permitiendo una interacción segura con los elementos de la UI.

¿Cuáles son los beneficios de usar BackgroundWorker para el procesamiento de PDF en aplicaciones .NET antiguas?

BackgroundWorker ofrece una manera sencilla de implementar operaciones asincrónicas en aplicaciones antiguas de WinForms, proporcionando un modelo simple para manejar tareas como el procesamiento de PDF con IronPDF mientras se mantiene la UI responsiva.

¿Puedo cancelar una tarea de generación de PDF usando BackgroundWorker?

Sí, BackgroundWorker soporta la cancelación de tareas. Puedes implementar la cancelación comprobando la propiedad CancellationPending en tu controlador de eventos DoWork y terminando la tarea de manera elegante.

¿Cómo puedo rastrear el progreso de la generación de PDF usando BackgroundWorker?

Puedes reportar el progreso desde el método DoWork usando el método ReportProgress de BackgroundWorker. Esto te permite actualizar la UI con información de progreso durante la generación de PDF.

¿Por qué deberían evitarse las actualizaciones de UI en el controlador de eventos DoWork?

Las actualizaciones de UI deberían evitarse en el controlador de eventos DoWork porque se ejecuta en un hilo separado. La manipulación directa de la UI podría llevar a problemas de hilos. En su lugar, utiliza los eventos RunWorkerCompleted o ProgressChanged para las actualizaciones de UI.

¿Qué pasos están involucrados en configurar un BackgroundWorker para la generación de PDF en C#?

Configurar un BackgroundWorker implica inicializar el trabajador, manejar los eventos DoWork y RunWorkerCompleted, y comenzar la tarea usando RunWorkerAsync. Esta configuración se usa para realizar tareas como la generación de PDF con IronPDF.

¿Es necesario usar patrones modernos async/await para la generación de PDF en aplicaciones .NET?

Aunque los patrones modernos async/await son recomendados para nuevas aplicaciones, BackgroundWorker sigue siendo útil en aplicaciones antiguas de WinForms para manejar tareas asincrónicas como la generación de PDF con IronPDF, debido a su simplicidad y facilidad de uso.

Jacob Mellor, Director de Tecnología @ Team Iron
Director de Tecnología

Jacob Mellor es Director de Tecnología en Iron Software y un ingeniero visionario que lidera la tecnología PDF en C#. Como el desarrollador original detrás de la base de código central de Iron Software, ha moldeado la arquitectura de productos de la compañía desde ...

Leer más