跳至頁尾內容
.NET幫助

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

using IronPDF 生成PDF是 .NET開發人員常見的任務—尤其是在建立動態報告、發票或文件自動化系統時。 但如果您曾經在Windows Forms或WPF應用程式的主UI執行緒上觸發PDF生成,您可能會看到使用者介面凍結或無響應。這在呈現大型HTML內容或處理複雜的PDF佈局時尤其真實。

這就是C# BackgroundWorker類的用途。 本文將介紹如何將IronPDF與 BackgroundWorker 整合,以在桌面應用程式中處理非同步操作而不鎖住UI。

為什麼要在IronPDF中使用BackgroundWorker?

保持您的UI響應靈敏

當您在主執行緒上運行CPU密集型或IO綁定任務(例如PDF生成)時,會鎖住UI。 使用者在應用程式忙碌時無法點擊、拖動或互動。 通過使用BackgroundWorker物件,您可以將工作移至另一個執行緒,從而在後台處理時保持介面快速回應並可使用。

非常適合報告生成和長期運行任務

如果您的應用涉及匯出資料、將HTML轉換為PDF或呈現詳細報告,將其解除安裝到後台工作器能讓您的應用更專業和性能更高。

與舊版WinForms應用相容

雖然現代應用往往使用async/await,但許多舊專案仍受益於BackgroundWorker帶來的簡單性及其在Visual Studio中的設計時支持。

什麼是IronPDF?

C# BackgroundWorker(開發人員如何使用):圖1 - IronPDF

IronPDF 是一個強大的.NET程式庫,專為在C#中生成、編輯和處理PDF文件而設計。 它在後端使用無頭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返回任何方法結果。

結論

將BackgroundWorker與IronPDF結合使用,您可以在後台執行緒上執行繁重的PDF渲染任務,保持應用程式的響應性。這在需要在長期運行任務如PDF生成過程中進行響應的UI更新的WinForms或WPF應用中尤其有價值。

通過處理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生成的進度?

您可以透過DoWork方法中的ReportProgress方法報告進度。這使您可以在PDF生成期間使用進度資訊更新UI。

為什麼應避免在DoWork事件處理程式中進行UI更新?

應避免在DoWork事件處理程式中進行UI更新,因為它在單獨的執行緒上運行。直接的UI操作可能會導致執行緒問題。相反,使用RunWorkerCompleted或ProgressChanged事件進行UI更新。

設置BackgroundWorker進行C#中的PDF生成涉及哪些步驟?

設置BackgroundWorker涉及初始化工作程式,處理DoWork和RunWorkerCompleted事件,並使用RunWorkerAsync啟動任務。此設置用於執行像使用IronPDF進行PDF生成這樣的任務。

在.NET應用程式中進行PDF生成需要使用現代的async/await模式嗎?

雖然建議在新應用程式中使用現代的async/await模式,但在較舊的WinForms應用程式中,BackgroundWorker仍然對於處理像使用IronPDF進行的非同步任務非常有用,因為它簡單易用。

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天。
聊天
電子郵件
給我打電話