跳過到頁腳內容
.NET幫助

C# BackgroundWorker(開發者工作方式)

使用 IronPDF 產生 PDF 是 .NET 開發人員的常見工作 - 尤其是在建立動態報表、發票或文件自動化系統時。 但是,如果您曾經在 Windows 窗體或 WPF 應用程式的主 UI 線程上觸發 PDF 產生,您很可能會看到您的使用者介面凍結或變得反應不良。在渲染大型 HTML 內容或處理複雜的 PDF 佈局時尤其如此。

這就是 C# BackgroundWorker 類的用武之地。 本文將介紹如何將 IronPDF 與 BackgroundWorker 整合,以處理桌面應用程式中的異步操作,而不會鎖定 UI。

為何使用 IronPDF 的 BackgroundWorker?

保持您的 UI 靈活反應

當您在主線程上執行類似產生 PDF 的 CPU 高負荷或 IO 綁定任務時,就會鎖定 UI。 使用者無法在應用程式忙碌時點擊、拖曳或互動。 透過使用 BackgroundWorker 物件,您可以將工作移至獨立的線程,在背景處理期間保持介面的敏捷性與可用性。

最適合報告生成和長時間執行的任務

如果您的應用程式涉及匯出資料、將 HTML 轉換為 PDF 或呈現詳細報告-將這些工作載入背景工作人員,會讓您的應用程式更專業、效能更高。

與傳統 WinForms 應用程式相容

儘管現代應用程式經常使用 async/await,但許多舊專案仍因 BackgroundWorker 的簡單性及 Visual Studio 的設計時支援而受惠。

什麼是 IronPDF?

C# BackgroundWorker (How it Works for Developers):圖 1 - IronPdf

IronPDF 是一個功能強大的 .NET 函式庫,專為在 C# 中產生、編輯和處理 PDF 文件而設計。 它在引擎蓋下使用無頭 Chromium 瀏覽器,讓開發人員可以將 HTML、CSS、JavaScript,甚至複雜的網頁轉換成精確、印刷品質的 PDF。 與傳統的 PDF 產生器不同,IronPDF 能將文件渲染得與在瀏覽器中顯示的一模一樣,即像素對像素地匹配版面、字型、圖像和樣式。

主要功能

  • HTML 至 PDF 轉換 - 將 HTML 字串、URL 或完整網頁渲染為 PDF。
  • 圖片與文字渲染 - 以程式化的方式新增頁眉、頁腳、水印和圖片。
  • Merging and Splitting PDFs - 合併多個文件或抽取特定頁面。
  • Form Filling and Annotations - 使用互動式 PDF 表單。
  • No External Dependencies - 不需要安裝 Adobe Acrobat 或 Microsoft Office 即可運作。

IronPDF 支援 .NET Framework、.NET Core 及 .NET 6/7+,因此適用於桌面及網頁型 .NET 應用程式。

透過 NuGet 安裝 IronPDF。

要開始使用,請使用 NuGet Package Manager 將 IronPDF 安裝到您的專案中:

Install-Package IronPdf

這將添加所有必要的參考資料,以便您可以開始使用 IronPDF 的 ChromePdfRenderer、HtmlToPdf 以及其他強大功能。

在本範例中,我們將採用一個以 Visual Studio 建立的 Windows Forms 應用程式,其中有一個按鈕可觸發 PDF 的產生,並有一個標籤可指示過程何時完成。

為 IronPDF 實作 BackgroundWorker。

現在,我們將透過以下的程式碼範例,以結構化、安全的方式來分解 BackgroundWorker 的使用過程:

步驟 1 - 定義 BackgroundWorker

您可以在設計器或程式碼中建立和設定 BackgroundWorker。 以下是程式碼的做法:

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

這會初始化 Worker,並為背景執行和完成設定必要的事件。

步驟 2 - 處理 DoWork 事件

DoWork 方法在不同的執行緒上執行,執行背景作業 (產生 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

注意:您無法在此與 UI 控制項互動,因為它是在 工作線程上執行。

步驟 3 - 使用 RunWorkerCompleted 來通知完成

一旦背景線程完成,您就可以安全地將結果更新 UI。

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

步驟 4 - 從 UI 觸發 BackgroundWorker

新增"開始"按鈕,點選後可執行背景工作:

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

完整程式碼範例

以下是將所有內容串連在一起的單一 Windows Forms 工作片段:

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

表格輸出

C# BackgroundWorker (How it Works for Developers):圖 2 - PDF 建立後的表單輸出

PDF輸出

C# BackgroundWorker (How it Works for Developers):圖 3 - PDF 輸出

最佳實務

避免在 DoWork 中存取 UI

DoWork 事件處理器在不同的執行緒上執行,因此您無法直接存取 UI 元素。 使用 RunWorkerCompleted 或控制 Invoke() 呼叫進行安全的 UI 更新。

支援異步取消

如果您的任務較長,請啟用 WorkerSupportsCancellation = true 並在 DoWork 內監視 CancellationPending,以支援請求的取消。

使用報告進度更新(可選)

您可以啟用 WorkerReportsProgress = true 並使用 ProgressChanged 事件來顯示進度列或訊息。

驗證輸入參數

使用 RunWorkerAsync(argument) 時,請在 DoWork 中驗證參數,並透過 e.Result.RunWorkerAsync(argument) 傳回任何方法結果。

結論

使用 IronPDF 的 BackgroundWorker 可讓您在背景線程上執行繁重的 PDF 渲染任務,保持應用程式的反應速度。這在使用 WinForms 或 WPF 應用程式時特別有價值,因為這些應用程式需要在 PDF 生成等長時間執行的任務中進行回應式 UI 更新。

透過處理 dowork 事件處理器、監控最終結果,並在 runworkercompleted 事件中安全地更新使用者介面,就能確保您的背景作業順利執行。

雖然 async/await 通常是新應用程式的首選,但 BackgroundWorker 仍是舊式或 WinForms 專案的可靠工具。 無論您是匯出報表或即時產生文件,這種方法都能幫助您充分發揮 IronPDF 的優點,同時保持應用程式的流暢性和人性化。

準備好親身體驗了嗎?

下載 免費的 IronPDF 試用版,立即開始使用 C# 建立功能強大的 PDF 解決方案。 試用版可讓您完全使用本文所展示的功能 - 無需信用卡。

常見問題解答

如何在 C# Windows Forms 應用程式中執行 PDF 產生,而不會凍結使用者介面?

您可以利用 C# BackgroundWorker 類別與 IronPDF 結合,在單獨的執行緒上執行 PDF 生成。這可確保主 UI 線程在過程中保持回應。

BackgroundWorker 中 DoWork 事件處理器的作用是什麼?

DoWork 事件處理器是您執行長時間執行任務的地方,例如使用 IronPDF 產生 PDF。它在與 UI 獨立的執行緒上執行,可避免介面凍結。

如何使用背景 PDF 生成任务的结果更新 UI?

使用 RunWorkerCompleted 事件以 PDF 生成的結果更新 UI。此事件會在背景任務完成後觸發,允許與 UI 元素進行安全的互動。

在舊版 .NET 應用程式中使用 BackgroundWorker 處理 PDF 有什麼好處?

BackgroundWorker 提供了在傳統 WinForms 應用程式中實作異步操作的直接方法,提供了一個簡單的模型來處理工作,例如使用 IronPDF 處理 PDF,同時保持 UI 的反應速度。

我可以取消使用 BackgroundWorker 生成 PDF 的任務嗎?

是的,BackgroundWorker 支援取消任務。您可以透過檢查 DoWork 事件處理器中的 CancellationPending 屬性,並優雅地終止任務來實作取消。

如何使用 BackgroundWorker 追蹤生成 PDF 的進度?

您可以使用 BackgroundWorker 的 ReportProgress 方法來報告 DoWork 方法的進度。這可讓您在 PDF 製作過程中,以進度資訊更新 UI。

為什麼在 DoWork 事件處理器中應該避免 UI 更新?

應避免在 DoWork 事件處理器中更新 UI,因為它是在獨立的線程中執行。直接操作 UI 可能會導致線程問題。取而代之,使用 RunWorkerCompleted 或 ProgressChanged 事件進行 UI 更新。

在 C# 中為 PDF 生成設定 BackgroundWorker 涉及哪些步驟?

設定 BackgroundWorker 涉及初始化 Worker、處理 DoWork 和 RunWorkerCompleted 事件,以及使用 RunWorkerAsync 來啟動任務。此設定可用於執行 PDF 產生等工作,例如使用 IronPDF。

是否有必要在 .NET 應用程式中使用現代的 async/await 模式來產生 PDF?

雖然新應用程式建議使用現代的 async/await 模式,但由於 BackgroundWorker 簡單易用,因此在舊版 WinForms 應用程式中,BackgroundWorker 仍然可用於處理異步任務,例如使用 IronPDF 產生 PDF。

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 技術的創新,同時指導新一代技術領袖。