Saltar al pie de página
.NET AYUDA

C# Event Handler (Cómo Funciona para Desarrolladores)

En las aplicaciones modernas de .NET, la programación orientada a eventos juega un papel vital en la mejora de la capacidad de respuesta y la garantía de experiencias de usuario fluidas. Cuando tareas como la generación de PDF toman tiempo, no querrás bloquear el hilo principal. En cambio, puedes usar manejadoress de eventos para ejecutar tareas asíncronamente y reaccionar una vez que ocurra un evento, haciendo tu aplicación más interactiva y receptiva.

En esta guía, te mostraremos cómo integrar métodos de manejo de eventos de C# con IronPDF para flujos de trabajo de PDF sin problemas en entornos de escritorio y web. Ya sea que estés utilizando WinForms, WPF o cualquier otra plataforma basada en el lenguaje de programación C#, esta guía te cubre.

Cómo configurar su proyecto IronPDF

Antes de profundizar en el manejo de eventos, configuremos rápidamente IronPDF en tu proyecto .NET.

Instalar IronPDF a través de NuGet

En la Consola del Administrador de Paquetes de Visual Studio, ejecuta:

Install-Package IronPdf

Esto instala todo lo necesario para comenzar a generar PDF utilizando IronPDF.

Generación básica de PDF con IronPDF

Aquí tienes un rápido ejemplo para asegurar que IronPDF está funcionando:

using IronPdf;
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello from IronPDF!</h1>");
pdf.SaveAs("example.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello from IronPDF!</h1>");
pdf.SaveAs("example.pdf");
Imports IronPdf
Private renderer = New ChromePdfRenderer()
Private pdf = renderer.RenderHtmlAsPdf("<h1>Hello from IronPDF!</h1>")
pdf.SaveAs("example.pdf")
$vbLabelText   $csharpLabel

Una vez que esto funcione, estarás listo para agregar campos de eventos, conectar delegados registrados, y usar tipos de delegados para crear flujos de trabajo orientados a eventos.

C# Fundamentos de controladores de eventos para desarrolladores .NET

Los fundamentos de la programación dirigida por eventos

Con la programación orientada a eventos, tu aplicación responde cuando ocurre un evento, como la finalización de la generación de un PDF. C# utiliza delegados como punteros de función seguros para definir cómo debe reaccionar tu aplicación.

Normalmente, declaras eventos usando la palabra clave event, los conectas a métodos de manejo de eventos, y pasas datos usando subclases personalizadas de EventArgs.

Declarar un evento con la palabra clave event

C# utiliza la palabra clave event para declarar miembros de eventos. Por ejemplo:

public event EventHandler PdfGenerated;
public event EventHandler PdfGenerated;
Public Event PdfGenerated As EventHandler
$vbLabelText   $csharpLabel

Esta línea declara un campo de evento denominado PdfGenerated. Utiliza EventHandler, un delegado integrado con la siguiente lista de parámetros: (object sender, EventArgs e), a menudo referido como el patrón de nombres para eventos en .NET.

Definición y suscripción a eventos en C#;

Añadir métodos a eventos mediante delegados

El soporte de eventos de C# permite agregar métodos dinámicamente en tiempo de ejecución utilizando la sintaxis +=. Así es como:

pdfService.PdfGenerated += (s, e) =>
{
    Console.WriteLine("PDF was generated!");
};
pdfService.PdfGenerated += (s, e) =>
{
    Console.WriteLine("PDF was generated!");
};
AddHandler pdfService.PdfGenerated, Sub(s, e)
	Console.WriteLine("PDF was generated!")
End Sub
$vbLabelText   $csharpLabel

Esta clase suscriptora escucha el evento PdfGenerated y ejecuta una llamada de método cuando se activa.

Datos de eventos personalizados

Para pasar datos de eventos como la ruta del archivo generado, define una clase derivada de EventArgs:

public class PdfGeneratedEventArgs : EventArgs
{
    public string FilePath { get; set; } // returned value
}
public class PdfGeneratedEventArgs : EventArgs
{
    public string FilePath { get; set; } // returned value
}
Public Class PdfGeneratedEventArgs
	Inherits EventArgs

	Public Property FilePath() As String ' -  returned value
End Class
$vbLabelText   $csharpLabel

Luego redefine el evento usando un tipo de delegado genérico:

public event EventHandler<PdfGeneratedEventArgs> PdfGenerated;
public event EventHandler<PdfGeneratedEventArgs> PdfGenerated;
Public Event PdfGenerated As EventHandler(Of PdfGeneratedEventArgs)
$vbLabelText   $csharpLabel

Esto te da datos estructurados y seguros cuando se activa el evento, haciendo tu lógica de respuesta más poderosa.

Manejo de múltiples eventos

Puedes definir múltiples eventos:

public event EventHandler PdfGenerationStarted;
public event EventHandler<PdfGeneratedEventArgs> PdfGenerationCompleted;
public event EventHandler PdfGenerationStarted;
public event EventHandler<PdfGeneratedEventArgs> PdfGenerationCompleted;
Public Event PdfGenerationStarted As EventHandler
Public Event PdfGenerationCompleted As EventHandler(Of PdfGeneratedEventArgs)
$vbLabelText   $csharpLabel

Cada campo de evento es manejado por una clase suscriptora, permitiendo métodos de manejo de eventos distintos por etapa. Esta separación de intereses tiene sentido en flujos de trabajo complejos.

Uso de controladores de eventos con IronPDF

Al generar PDFs grandes, es lógico ejecutar IronPDF en un hilo de fondo y notificar a la interfaz de usuario cuando se complete. Así es como el diseño orientado a eventos puede ayudar:

  • Usa un BackgroundWorker para generar PDFs asíncronamente
  • Genera eventos cuando cada etapa se completa
  • Pasa datos de resultados usando objetos de datos de evento

Ejemplo de código - Generar PDF de forma asíncrona

El siguiente ejemplo es el código completo para usar el manejo de eventos con IronPDF:

using System;
using System.ComponentModel;
using IronPdf;
namespace IronPdfEventHandlerExample
{
    // 1. Define custom EventArgs to carry event data
    public class PdfGeneratedEventArgs : EventArgs
    {
        public string FilePath { get; set; }
    }
    // 2. Main class with event, BackgroundWorker, and logic
    public class PdfGenerator
    {
        // Declare the public event using EventHandler<T>
        public event EventHandler<PdfGeneratedEventArgs> PdfGenerated;
        private readonly BackgroundWorker _worker;
        public PdfGenerator()
        {
            _worker = new BackgroundWorker();
            _worker.DoWork += OnDoWork;
            _worker.RunWorkerCompleted += OnRunWorkerCompleted;
        }
        // Start the async operation
        public void GenerateAsync(string html, string outputPath)
        {
            _worker.RunWorkerAsync(new Tuple<string, string>(html, outputPath));
        }
        // Perform PDF generation in background
        private void OnDoWork(object sender, DoWorkEventArgs e)
        {
            var (html, path) = (Tuple<string, string>)e.Argument;
            var renderer = new HtmlToPdf();
            var pdf = renderer.RenderHtmlAsPdf(html);
            pdf.SaveAs(path);
            e.Result = path;
        }
        // Notify subscribers when the PDF is ready
        private void OnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var path = e.Result as string;
            PdfGenerated?.Invoke(this, new PdfGeneratedEventArgs { FilePath = path });
        }
    }
    // 3. Program to wire it all together
    class Program
    {
        public static void Main(string[] args)
        {
            var generator = new PdfGenerator();
            // Subscribe to the PdfGenerated event
            generator.PdfGenerated += OnPdfGenerated;
            Console.WriteLine("Generating PDF asynchronously...");
            generator.GenerateAsync("<h1>Hello, IronPDF!</h1>", "output.pdf");
            Console.WriteLine("Press any key to exit after generation.");
            Console.ReadKey();
        }
        // Event handler for when the PDF is ready
        static void OnPdfGenerated(object sender, PdfGeneratedEventArgs e)
        {
            Console.WriteLine($"PDF generated at: {e.FilePath}");
        }
    }
}
using System;
using System.ComponentModel;
using IronPdf;
namespace IronPdfEventHandlerExample
{
    // 1. Define custom EventArgs to carry event data
    public class PdfGeneratedEventArgs : EventArgs
    {
        public string FilePath { get; set; }
    }
    // 2. Main class with event, BackgroundWorker, and logic
    public class PdfGenerator
    {
        // Declare the public event using EventHandler<T>
        public event EventHandler<PdfGeneratedEventArgs> PdfGenerated;
        private readonly BackgroundWorker _worker;
        public PdfGenerator()
        {
            _worker = new BackgroundWorker();
            _worker.DoWork += OnDoWork;
            _worker.RunWorkerCompleted += OnRunWorkerCompleted;
        }
        // Start the async operation
        public void GenerateAsync(string html, string outputPath)
        {
            _worker.RunWorkerAsync(new Tuple<string, string>(html, outputPath));
        }
        // Perform PDF generation in background
        private void OnDoWork(object sender, DoWorkEventArgs e)
        {
            var (html, path) = (Tuple<string, string>)e.Argument;
            var renderer = new HtmlToPdf();
            var pdf = renderer.RenderHtmlAsPdf(html);
            pdf.SaveAs(path);
            e.Result = path;
        }
        // Notify subscribers when the PDF is ready
        private void OnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var path = e.Result as string;
            PdfGenerated?.Invoke(this, new PdfGeneratedEventArgs { FilePath = path });
        }
    }
    // 3. Program to wire it all together
    class Program
    {
        public static void Main(string[] args)
        {
            var generator = new PdfGenerator();
            // Subscribe to the PdfGenerated event
            generator.PdfGenerated += OnPdfGenerated;
            Console.WriteLine("Generating PDF asynchronously...");
            generator.GenerateAsync("<h1>Hello, IronPDF!</h1>", "output.pdf");
            Console.WriteLine("Press any key to exit after generation.");
            Console.ReadKey();
        }
        // Event handler for when the PDF is ready
        static void OnPdfGenerated(object sender, PdfGeneratedEventArgs e)
        {
            Console.WriteLine($"PDF generated at: {e.FilePath}");
        }
    }
}
Imports System
Imports System.ComponentModel
Imports IronPdf
Namespace IronPdfEventHandlerExample
	' 1. Define custom EventArgs to carry event data
	Public Class PdfGeneratedEventArgs
		Inherits EventArgs

		Public Property FilePath() As String
	End Class
	' 2. Main class with event, BackgroundWorker, and logic
	Public Class PdfGenerator
		' Declare the public event using EventHandler<T>
		Public Event PdfGenerated As EventHandler(Of PdfGeneratedEventArgs)
		Private ReadOnly _worker As BackgroundWorker
		Public Sub New()
			_worker = New BackgroundWorker()
			AddHandler _worker.DoWork, AddressOf OnDoWork
			AddHandler _worker.RunWorkerCompleted, AddressOf OnRunWorkerCompleted
		End Sub
		' Start the async operation
		Public Sub GenerateAsync(ByVal html As String, ByVal outputPath As String)
			_worker.RunWorkerAsync(New Tuple(Of String, String)(html, outputPath))
		End Sub
		' Perform PDF generation in background
		Private Sub OnDoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
'INSTANT VB TODO TASK: VB has no equivalent to C# deconstruction declarations:
			var(html, path) = (Tuple(Of String, String))e.Argument
			Dim renderer = New HtmlToPdf()
			Dim pdf = renderer.RenderHtmlAsPdf(html)
			pdf.SaveAs(path)
			e.Result = path
		End Sub
		' Notify subscribers when the PDF is ready
		Private Sub OnRunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
			Dim path = TryCast(e.Result, String)
			RaiseEvent PdfGenerated(Me, New PdfGeneratedEventArgs With {.FilePath = path})
		End Sub
	End Class
	' 3. Program to wire it all together
	Friend Class Program
		Public Shared Sub Main(ByVal args() As String)
			Dim generator = New PdfGenerator()
			' Subscribe to the PdfGenerated event
			AddHandler generator.PdfGenerated, AddressOf OnPdfGenerated
			Console.WriteLine("Generating PDF asynchronously...")
			generator.GenerateAsync("<h1>Hello, IronPDF!</h1>", "output.pdf")
			Console.WriteLine("Press any key to exit after generation.")
			Console.ReadKey()
		End Sub
		' Event handler for when the PDF is ready
		Private Shared Sub OnPdfGenerated(ByVal sender As Object, ByVal e As PdfGeneratedEventArgs)
			Console.WriteLine($"PDF generated at: {e.FilePath}")
		End Sub
	End Class
End Namespace
$vbLabelText   $csharpLabel

Salida de Consola

C# Event Handler (Cómo Funciona para Desarrolladores): Figura 1 - Salida de Consola

Salida de PDF

C# Event Handler (Cómo Funciona para Desarrolladores): Figura 2 - Salida PDF

Características principales de este código

  • public event EventHandler<PdfGeneratedEventArgs>: Declara un evento fuertemente tipado
  • PdfGeneratedEventArgs: Clase personalizada para datos de eventos
  • BackgroundWorker: Permite ejecución asíncrona para evitar bloqueo de UI
  • ?.Invoke(...): Invocación segura de eventos
  • Tuple<string, string>: Pasa HTML y ruta de salida al hilo de fondo

Consejos para trabajar con eventos en .NET

1. Evitar el bloqueo de hilos de interfaz de usuario

Usa manejadores de eventos como RunWorkerCompleted para realizar actualizaciones de UI solo después de que las tareas de fondo se completen.

2. Manejar excepciones con gracia

Envuelve tu lógica de trabajo en bloques try-catch dentro de DoWork y pasa excepciones a RunWorkerCompleted a través de e.Error.

if (e.Error != null)
{
    MessageBox.Show("Error: " + e.Error.Message);
}
if (e.Error != null)
{
    MessageBox.Show("Error: " + e.Error.Message);
}
If e.Error IsNot Nothing Then
	MessageBox.Show("Error: " & e.Error.Message)
End If
$vbLabelText   $csharpLabel

3. Darse de baja cuando sea necesario

En aplicaciones de larga duración, cancela la suscripción a eventos cuando ya no se necesiten para evitar fugas de memoria:

pdfWorker.DoWork -= PdfWorker_DoWork;
pdfWorker.DoWork -= PdfWorker_DoWork;
pdfWorker.DoWork -= PdfWorker_DoWork
$vbLabelText   $csharpLabel

Reflexiones finales

Usar manejadores de eventos, tipos de delegados, y campos de eventos con IronPDF agrega un borde moderno y receptivo a las aplicaciones .NET. Ya sea que estés generando documentos en una clase base, creando lógica reutilizable en clases derivadas, o simplemente explorando el modelo de eventos de .NET, este patrón es escalable y limpio.

Cuándo utilizar este enfoque

  • Quieres generar un evento cuando una tarea se complete
  • Necesitas separación limpia entre lógica e IU
  • Estás trabajando con BackgroundWorker, eventos y delegados
  • Prefieres la mecánica de punto de función segura de C#

Alternativas a explorar

  • async/await y Task.Run para flujos de trabajo más nuevos
  • IProgress para actualizaciones en tiempo real durante operaciones largas, IronPDF combinado con eventos de C# hace que sea sencillo crear aplicaciones de generación de PDF potentes y receptivas con la usabilidad del mundo real en mente. ¿Listo para implementar la generación de PDF orientada a eventos en tu aplicación .NET? Pruébalo con la prueba gratuita de IronPDF y mantén a tus usuarios felices con experiencias fluidas y no bloqueantes!

Preguntas Frecuentes

¿Cómo puedo convertir HTML a PDF en C#?

Puedes usar el método RenderHtmlAsPdf de IronPDF para convertir cadenas de HTML en PDFs. También puedes convertir archivos HTML a PDFs usando RenderHtmlFileAsPdf.

¿Por qué es importante la programación orientada a eventos en aplicaciones .NET?

La programación orientada a eventos es vital en aplicaciones .NET para mejorar la capacidad de respuesta y garantizar experiencias de usuario fluidas al permitir que las tareas se ejecuten de forma asíncrona sin bloquear el hilo principal.

¿Cómo se instala la herramienta necesaria para la generación de PDF en un proyecto .NET?

Puedes instalar IronPDF a través de NuGet ejecutando el comando 'Install-Package IronPdf' en la Consola del Administrador de Paquetes de Visual Studio.

¿Cómo se declara un evento en C#?

En C#, los eventos se declaran usando la palabra clave 'event', a menudo con un tipo delegado como 'EventHandler'. Por ejemplo: public event EventHandler PdfGenerated;.

¿Qué es un delegado en el manejo de eventos de C#?

Un delegado en C# es un puntero de función seguro para tipos que te permite definir métodos que pueden ser llamados en respuesta a un evento.

¿Cómo puedes agregar métodos a los eventos en C#?

Puedes agregar métodos a los eventos en C# dinámicamente en tiempo de ejecución utilizando la sintaxis '+=' para suscribirte a los eventos.

¿Cuál es el propósito de crear una clase personalizada de EventArgs?

Una clase personalizada de EventArgs se utiliza para pasar datos específicos del evento, como una ruta de archivo, a los controladores de eventos de una manera estructurada y segura para tipos.

¿Por qué deberías usar un BackgroundWorker para generar PDFs grandes?

Usar un BackgroundWorker te permite ejecutar tareas de generación de PDF de manera asíncrona, evitando que la interfaz de usuario se bloquee y mejorando la experiencia del usuario.

¿Cuáles son algunos consejos para trabajar con eventos en .NET?

Consejos clave incluyen evitar el bloqueo del hilo de la interfaz de usuario actualizando la interfaz solo después de completar las tareas en segundo plano, manejar excepciones con cuidado y dar de baja los eventos cuando ya no se necesiten para evitar pérdidas de memoria.

¿Cuáles son las alternativas al uso de controladores de eventos en .NET?

Las alternativas incluyen el uso de async/await y Task.Run para flujos de trabajo más nuevos e IProgress para actualizaciones en tiempo real durante operaciones largas.

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