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?

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
這會初始化 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
注意:您無法在此與 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
步驟 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
完整程式碼範例
以下是將所有內容串連在一起的單一 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
表格輸出

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 解決方案。 試用版可讓您完全使用本文所展示的功能 - 無需信用卡。
常見問題解答
如何在不凍結 UI 的情況下,在 C# Windows Forms 應用程式中執行 PDF 生成?
您可以使用C# BackgroundWorker類別與IronPDF結合來在單獨的線程上執行 PDF 生成。這可確保主 UI 線程在過程中保持響應。
DoWork 事件處理程序在 BackgroundWorker 中的作用是什麼?
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# 中設置 BackgroundWorker 進行 PDF 生成涉及哪些步驟?
設置 BackgroundWorker 涉及初始化工人、處理 DoWork 和 RunWorkerCompleted 事件,以及使用 RunWorkerAsync 啟動任務。此設置用於執行諸如使用 IronPDF 生成 PDF 之類的任務。
在 .NET 應用程式中進行 PDF 生成是否必須使用現代 async/await 模式?
雖然對於新應用程式建議使用現代 async/await 模式,但在較舊的 WinForms 應用程式中,BackgroundWorker 在處理像 IronPDF 這樣的異步任務時,由於其簡單性和易用性,仍然很有用。


