跳過到頁腳內容
.NET幫助

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

使用IronPDF生成 PDF 是 .NET 開發人員的常見任務,尤其是在構建動態報告、發票或文件自動化系統時。 但如果您曾在 Windows 窗體或 WPF 應用中在主 UI 線程上觸發 PDF 生成,您可能會看到用戶界面卡頓或無響應。當渲染大型 HTML 內容或處理複雜 PDF 布局時尤其如此。

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

為什麼要將 BackgroundWorker 與 IronPDF 結合使用?

保持 UI 響應性

當您在主線程上運行大量 CPU 或 IO 綁定任務(如 PDF 生成)時,它會鎖定 UI。 用戶在忙碌時無法點擊、拖動或與應用程序交互。 通過使用 BackgroundWorker 對象,您可以將工作轉移到一個單獨的線程中,使您的界面在後台處理過程中保持靈活和可用。

非常適合報告生成和長時間運行的任務

如果您的應用涉及數據導出、將 HTML 轉換為 PDF 或渲染詳細報告,將其交給後台工作者可以使您的應用程序更加專業和高效。

與傳統的 WinForms 應用兼容

儘管現代應用程序經常使用 async/await,但許多舊項目仍受益於 BackgroundWorker 的簡單性和 Visual Studio 中的設計時支持。

什麼是 IronPDF?

C# BackgroundWorker (對開發者的作用): 圖 1 - IronPDF

IronPDF 是用於生成、編輯和處理 C# 中 PDF 文檔的強大 .NET 庫。 它在底層使用無頭的 Chromium 瀏覽器,使開發人員能夠將 HTML、CSS、JavaScript 甚至複雜的網頁轉換為準確的、打印質量的 PDF。 與傳統的 PDF 生成器不同,IronPDF 精確渲染文件,就像它們出現在瀏覽器中一樣,匹配佈局、字體、圖像和樣式,逐像素展現。

主要功能

  • HTML 到 PDF 的轉換 - 渲染 HTML 字符串、URL 或完整的網頁為 PDF。
  • 圖像和文本渲染 - 程序化地添加頁眉、頁腳、水印和圖像。
  • 合併和拆分 PDF - 合併多個文檔或提取特定頁面。
  • 表單填充和註釋 - 處理交互式 PDF 表單。
  • 無外部依賴項 - 無需安裝 Adobe Acrobat 或 Microsoft Office。

IronPDF 支持 .NET Framework、.NET Core 和 .NET 6/7+,使其非常適合桌面和基於網絡的 .NET 應用程序。

通過 NuGet 安裝 IronPDF

要開始使用,請通過 NuGet 包管理器將 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

這會初始化工作者並連接背景執行和完成所需的事件。

步驟 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 (對開發者的作用): 圖 2 - PDF 創建後的表單輸出

PDF 輸出

C# BackgroundWorker (對開發者的作用): 圖 3 - PDF 輸出

最佳實踐

避免在 DoWork 中訪問 UI

DoWork 事件處理器運行在不同的線程上,因此您不能直接訪問 UI 元素。 使用 RunWorkerCompleted 或控制 Invoke() 調用以安全更新 UI。

支持異步取消

如果您的任務很長,啟用 WorkerSupportsCancellation = true 並在 DoWork 中監控 CancellationPending 以支持請求的取消。

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

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

驗證輸入參數

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

結論

與 IronPDF 一起使用 BackgroundWorker 可以讓您在背景線程中執行繁重的 PDF 渲染任務,保持應用程序的響應性。這在處理需要響應性 UI 更新的 WinForms 或 WPF 應用中尤為有益,比如 PDF 生成等長時間運行的任務。

通過處理 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 這樣的異步任務時,由於其簡單性和易用性,仍然很有用。

Curtis Chau
技術作家

Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。