跳至頁尾內容
.NET幫助

C# 事件處理者(開發者工作方式)

在現代的.NET應用程式中,事件驅動編程在提高響應能力和確保流暢的使用者體驗方面發揮著重要作用。 當像PDF生成這樣的任務需要時間時,您不希望阻塞主執行緒。 相反,您可以使用事件處理器來異步執行任務,並在事件發生時做出反應,讓您的應用程式更加互動且響應迅速。

在本指南中,我們將向您展示如何結合C#事件處理方法與IronPDF,實現桌面和網路環境中的無縫PDF工作流程。 無論您使用的是WinForms、WPF,還是其他以C#程式語言為基礎的平台,本指南都能為您提供幫助。

設置您的IronPDF專案

在深入事件處理之前,讓我們快速設置IronPDF於您的.NET專案中。

透過NuGet安裝IronPDF

在Visual Studio的套件管理器主控台中,運行:

Install-Package IronPdf

這將安裝所有需要的東西,以開始使用IronPDF生成PDF。

使用IronPDF進行基本PDF生成

這是一個快速範例,以確保IronPDF正在工作:

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

一旦這個工作正常,您就可以準備新增事件欄位、註冊委託,並使用委託型別來建立事件驅動的工作流程。

針對.NET開發人員的C#事件處理基礎

事件驅動編程的基礎

使用事件驅動編程,您的應用程式會在事件發生時回應,例如PDF完成生成。 C#使用委託作為型別安全的函式指標,允許您定義應用程式應如何回應。

通常,您會使用event關鍵字聲明事件,將其連接到事件處理方法,並使用自定義EventArgs子類傳遞資料。

使用event關鍵字聲明事件

C#使用event關鍵字來聲明事件成員。 例如:

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

這行聲明了一個名為PdfGenerated的事件欄位。 它使用EventHandler,這是一個內建委託,具有以下參數列表:(object sender, EventArgs e)—通常被稱為.NET中事件的命名模式。

在C#中定義和訂閱事件

使用委託將方法新增到事件中

C#事件支持在運行時動態新增方法,使用+=語法。 方法如下:

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

此訂閱者類會監聽PdfGenerated事件並在觸發時執行方法調用。

自定義事件資料

要傳遞事件資料,如生成的文件路徑,從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

然後使用泛型委託型別:重新定義事件

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

當事件被觸發時,這可提供結構化、型別安全的資料,使您的回應邏輯更強大。

處理多個事件

您可以定義多個事件:

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

每個事件欄位由一個訂閱者類處理,允許在每個階段使用不同的事件處理方法。 這種關注點分離在複雜的工作流程中很有意義。

在IronPDF中使用事件處理器

在生成大型PDF時,將IronPDF運行在背景執行緒中並在完成時通知UI是合理的。 以下是事件驅動設計能夠如何提供幫助:

  • 使用BackgroundWorker異步生成PDF
  • 在每個階段完成時觸發事件
  • 使用事件資料物件傳遞結果資料

程式範例 – 異步生成PDF

以下範例是使用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(Of 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(html As String, outputPath As String)
            _worker.RunWorkerAsync(Tuple.Create(html, outputPath))
        End Sub

        ' Perform PDF generation in background
        Private Sub OnDoWork(sender As Object, e As DoWorkEventArgs)
            Dim args = DirectCast(e.Argument, Tuple(Of String, String))
            Dim html = args.Item1
            Dim path = args.Item2
            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(sender As Object, 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
    Module Program

        Sub Main(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 Sub OnPdfGenerated(sender As Object, e As PdfGeneratedEventArgs)
            Console.WriteLine($"PDF generated at: {e.FilePath}")
        End Sub
    End Module

End Namespace
$vbLabelText   $csharpLabel

控制台輸出

C#事件處理器(如何為開發者工作):圖1 - 控制台輸出

PDF輸出

C#事件處理器(如何為開發者工作):圖2 - PDF輸出

此程式碼的關鍵功能

  • public event EventHandler<PdfGeneratedEventArgs>: 聲明一個強型別事件
  • PdfGeneratedEventArgs: 事件資料的自定義類
  • BackgroundWorker: 允許異步執行以避免UI阻塞
  • ?.Invoke(...): 安全事件調用
  • Tuple<string, string>: 將HTML和輸出路徑傳遞到背景執行緒

在.NET中使用事件的提示

1. 避免阻塞UI執行緒

使用像RunWorkerCompleted這樣的事件處理器僅在背景任務完成後執行UI更新。

2. 優雅處理例外

在DoWork中將您的工作邏輯包裹在try-catch塊中,並透過e.Error將例外傳遞給RunWorkerCompleted。

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. 必要時取消訂閱

在長期運行的應用中,不再需要的時候取消訂閱事件,以避免記憶體洩漏:

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

總結

使用事件處理器、委託型別和事件欄位與IronPDF協同處理,為.NET應用新增了響應迅速、現代的優勢。 無論您是在基礎類中生成文件,還是在衍生類中建立可重複使用的邏輯,或者只是在探索.NET的事件模型,這種模式是可擴展且清晰的。

何時使用此方法

  • 您希望在任務完成時觸發一個事件
  • 您需要在邏輯和UI之間進行清晰的分離
  • 您正在使用BackgroundWorker、事件和委託
  • 您偏好C#的型別安全函式指標機制

可以探索的替代方案

  • Task.Run用於新的工作流程
  • IProgress<t>用於長時間運行操作的即時更新,IronPDF結合C#事件使其能簡單地建立功能強大且具有實際應用價值的響應迅速的PDF生成應用。 準備好在您的.NET應用程式中實現事件驅動的PDF生成了嗎? 使用IronPDF免費試用來實現,並讓您的使用者享受流暢、無阻塞的體驗!

常見問題

如何在C#中將HTML轉換成PDF?

您可以使用IronPDF的RenderHtmlAsPdf方法將HTML字串轉換成PDF。您也可以使用RenderHtmlFileAsPdf將HTML文件轉換為PDF。

為什麼事件驅動程式設計在.NET應用程式中很重要?

事件驅動程式設計在.NET應用程式中至關重要,因為它通過允許任務異步執行而不阻塞主執行緒來提高響應能力並確保順暢的使用者體驗。

如何在.NET專案中安裝必要的PDF生成工具?

您可以透過運行命令 'Install-Package IronPdf' 在Visual Studio的套件管理器控制台中安裝IronPDF。

如何在C#中宣告一個事件?

在C#中,事件是使用 'event' 關鍵字宣告的,通常與一個委派型別如 'EventHandler'一起使用。例如:public event EventHandler PdfGenerated;

在C#事件處理中,什麼是委派?

在C#中,委派是一種型別安全的函式指標,允許您定義可以作為事件回應調用的方法。

如何將方法新增到C#中的事件中?

您可以使用 '+=' 語法在運行時動態地將方法新增到C#中的事件中。

建立自定義EventArgs類的目的是什麼?

自定義EventArgs類用於以結構化和型別安全的方式將事件特定資料(例如文件路徑)傳遞給事件處理程式。

為什麼在生成大型PDF時應使用BackgroundWorker?

使用BackgroundWorker可以異步執行PDF生成任務,防止UI阻塞,從而改善使用者體驗。

在.NET中使用事件的一些提示是什麼?

關鍵提示包括避免阻塞UI執行緒,僅在背景任務完成後更新UI,優雅地處理異常,並在不再需要時取消訂閱事件以防止記憶體洩漏。

在.NET使用事件處理程式有哪些替代方法?

替代方法包括使用async/await和Task.Run進行新工作流程,及使用IProgress在長時間操作期間進行實時更新。

Jacob Mellor,首席技術官 @ Team Iron
首席技術官

Jacob Mellor是Iron Software的首席技術官,一位在C# PDF技術上開創先河的遠見工程師。作為Iron Software核心程式碼庫的原開發者,他從創立以來就一直在塑造公司的產品架構,與首席執行官Cameron Rimington一起將公司轉變為服務於NASA、特斯拉和全球政府公司的50多名人員的公司。

Jacob擁有曼徹斯特大學的土木工程一等榮譽學士學位(BEng),於1998-2001年之間獲得。在1999年於倫敦創辦他的第一家軟體公司並於2005年建立了他的第一批.NET元組件後,他專注於解決Microsoft生態系統中的複雜問題。

他的旗艦IronPDF和Iron Suite .NET程式庫在全球獲得了超過3000萬次NuGet安裝依據,他的基礎程式碼基繼續支援著世界各地開發者使用的工具。擁有25年的商業經驗和41年的程式設計專業知識,他仍專注於推動企業級C#、Java和Python PDF技術的創新,同時指導下一代技術領導者。

Iron 支援團隊

我們線上24小時,每週5天。
聊天
電子郵件
給我打電話