跳過到頁腳內容
.NET幫助

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

在現代的 .NET 應用程式中,事件驅動程式設計在改善回應能力和確保順暢的使用者體驗方面扮演著重要的角色。 當 PDF 生成等任務需要時間時,您不希望阻塞主線程。 相反地,您可以使用 事件處理程式 以異步方式執行任務,並在事件發生時立即反應,使您的應用程式更具互動性和反應能力。

在本指南中,我們將教您如何將 C# 事件處理方法與 IronPDF 整合,以在桌面和網頁環境中實現無縫的 PDF 工作流程。 無論您使用的是 WinForms、WPF 或任何其他以 C# 程式語言為基礎的平台,本指南都能滿足您的需求。

設定您的 IronPDF 專案。

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

透過 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

一旦完成這些工作,您就可以新增事件欄位、接線註冊委託,並使用委託類型來建立事件驅動的工作流程。

C# Event Handler Fundamentals for .NET Developers。

事件驅動程式設計的基礎

使用事件驅動程式設計,您的應用程式會在事件發生時回應,例如 PDF 完成產生。 C# 使用委託作為類型安全的函數指標,讓您可以定義應用程式應該如何反應。

您通常使用事件關鍵字來宣告事件,將事件連接到事件處理方法,並使用自訂的 EventArgs 子類來傳輸資料。

使用 event 關鍵字宣告事件

C# 使用事件關鍵字來宣告事件成員。 舉例來說

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

這一行宣告了一個名為 PdfGenerated 的事件欄位。 它使用 EventHandler,一個內建的 delegate,其參數清單如下:(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

這個 subscriber 類會監聽 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

然後使用一般的 delegate 類型重新定義事件:

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

每個事件欄位都由 subscriber 類別處理,讓每個階段都有不同的事件處理方法。 這樣的分工在複雜的工作流程中是合理的。

使用 IronPDF 的事件處理器。

生成大型 PDF 時,在背景線程上執行 IronPDF 並在完成時通知 UI 是合理的。 以下是事件驅動設計可以提供的幫助:

  • 使用 BackgroundWorker 以異步方式產生 PDF
  • 在每個階段完成時提出事件
  • 使用 事件資料物件傳遞結果資料

程式碼範例 - 非同步產生 PDFs

以下示例是使用 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

控制台輸出

C# Event Handler (How it Works for Developers):圖 1 - 控制台輸出

PDF輸出

C# Event Handler (How it Works for Developers):圖 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 for .NET 的事件處理器、委託類型和事件欄位,可為 .NET 應用程式增添反應迅速的現代優勢。 無論您是在基底類別中產生文件、在衍生類別中建立可重複使用的邏輯,或只是探索 .NET 的事件模型,此模式都是可擴充且乾淨的。

何時使用此方法

  • 您希望在任務完成時 產生事件
  • 您需要邏輯與使用者介面之間乾淨分離
  • 您正在使用 BackgroundWorker、事件和委派。
  • 您偏好 C# 的 類型安全函數點機制

探索其他方法

  • async/awaitTask.Run 適用於較新的工作流程
  • IProgress<T>可在長時間的操作中實時更新,IronPDF 結合 C# 事件可簡單地建立功能強大、反應靈敏的 PDF 產生應用程式,並將現實世界的可用性列入考量。 準備好在您的 .NET 應用程式中實作事件驅動的 PDF 生成了嗎?使用 IronPDF免費試用版試試看,讓您的使用者享受順暢、無阻塞的體驗!

常見問題解答

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

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

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

事件驅動程式設計在 .NET 應用程式中非常重要,可讓任務在不阻塞主線程下以非同步方式執行,從而改善反應速度並確保順暢的使用者體驗。

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

您可以透過 NuGet 安裝 IronPDF,方法是在 Visual Studio 的套件管理員控制台執行「Install-Package IronPdf」指令。

如何在 C# 中宣告事件?

在 C# 中,事件是使用「事件」關鍵字來宣告的,通常會搭配類似「EventHandler」的委託類型。例如public event EventHandler PdfGenerated;

C# 事件處理中的 delegate 是什麼?

C# 中的 delegate 是一種類型安全的函數指標,可讓您定義可回應事件而呼叫的方法。

如何在 C# 中為事件新增方法?

您可以在 C# 中使用「+=」語法在執行時動態地為事件新增方法,以訂閱事件。

建立自訂 EventArgs 類的目的是什麼?

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

為什麼要使用 BackgroundWorker 來產生大型 PDF?

使用 BackgroundWorker 可讓您以非同步方式執行 PDF 生成任務,防止 UI 阻塞並改善使用者體驗。

在 .NET 中使用事件有哪些技巧?

主要秘訣包括避免 UI 線程阻塞,方法是在背景任務完成後才更新 UI、優雅地處理異常,以及在不再需要時取消訂閱事件以防止記憶體洩漏。

除了在 .NET 中使用事件處理器之外,還有哪些替代方法?

替代方案包括使用 async/await 和 Task.Run 來處理較新的工作流程,以及使用 IProgress 來處理長時間作業期間的即時更新。

Jacob Mellor, Team Iron 首席技术官
首席技术官

Jacob Mellor 是 Iron Software 的首席技術官,作為 C# PDF 技術的先鋒工程師。作為 Iron Software 核心代碼的原作者,他自開始以來塑造了公司產品架構,與 CEO Cameron Rimington 一起將其轉變為一家擁有超過 50 名員工的公司,為 NASA、特斯拉 和 全世界政府機構服務。

Jacob 持有曼徹斯特大學土木工程一級榮譽学士工程學位(BEng) (1998-2001)。他於 1999 年在倫敦開設了他的第一家軟件公司,並於 2005 年製作了他的首個 .NET 組件,專注於解決 Microsoft 生態系統內的複雜問題。

他的旗艦產品 IronPDF & Iron Suite .NET 庫在全球 NuGet 被安裝超過 3000 萬次,其基礎代碼繼續為世界各地的開發工具提供動力。擁有 25 年的商業經驗和 41 年的編碼專業知識,Jacob 仍專注於推動企業級 C#、Java 及 Python PDF 技術的創新,同時指導新一代技術領袖。