Przejdź do treści stopki
POMOC .NET

C# BackgroundWorker (Jak to działa dla deweloperów)

Generowanie plików PDF za pomocą IronPDF jest częstym zadaniem dla programistów .NET — zwłaszcza podczas tworzenia dynamicznych raportów, faktur lub systemów automatyzacji dokumentów. Jeśli jednak kiedykolwiek uruchomiłeś generowanie pliku PDF w głównym wątku interfejsu użytkownika w aplikacji Windows Forms lub WPF, prawdopodobnie zauważyłeś, że interfejs użytkownika zawiesił się lub przestał reagować. Dzieje się tak zwłaszcza podczas renderowania dużych treści HTML lub przetwarzania złożonych układów PDF.

W tym miejscu pojawia się klasa C# BackgroundWorker. W tym artykule omówiono, jak zintegrować IronPDF z BackgroundWorker, aby obsługiwać operacje asynchroniczne w aplikacji desktopowej bez blokowania interfejsu użytkownika.

Dlaczego warto używać BackgroundWorker z IronPDF?

Zadbaj o responsywność interfejsu użytkownika

Gdy w głównym wątku uruchamiasz zadania obciążające procesor lub ograniczone przez operacje wejścia/wyjścia, takie jak generowanie plików PDF, interfejs użytkownika zawiesza się. Użytkownicy nie mogą klikać, przeciągać ani wchodzić w interakcję z aplikacją, gdy jest ona zajęta. Korzystając z obiektu BackgroundWorker, możesz przenieść pracę do oddzielnego wątku, dzięki czemu interfejs będzie działał płynnie i będzie dostępny podczas przetwarzania w tle.

Idealne do generowania raportów i zadań długotrwałych

Jeśli Twoja aplikacja wymaga eksportowania danych, konwersji HTML do PDF lub renderowania szczegółowych raportów — przeniesienie tych zadań do modułu działającego w tle sprawi, że Twoja aplikacja będzie bardziej profesjonalna i wydajna.

Kompatybilność ze starszymi aplikacjami WinForms

Chociaż nowoczesne aplikacje często wykorzystują async/await, wiele starszych projektów nadal korzysta z BackgroundWorker ze względu na jego prostotę i obsługę w czasie projektowania w Visual Studio.

Czym jest IronPDF?

C# BackgroundWorker (jak to działa dla programistów): Rysunek 1 — IronPDF

IronPDF to potężna biblioteka .NET przeznaczona do generowania, edycji i pracy z dokumentami PDF w języku C#. W tle wykorzystuje przeglądarkę Chromium bez interfejsu użytkownika, umożliwiając programistom konwersję HTML, CSS, JavaScript, a nawet złożonych stron internetowych na dokładne pliki PDF o jakości drukarskiej. W przeciwieństwie do tradycyjnych generatorów PDF, IronPDF renderuje dokumenty dokładnie tak, jak wyglądałyby w przeglądarce — zachowując układ, czcionki, obrazy i style piksel po pikselu.

Najważniejsze cechy

  • Konwersja HTML do PDF – renderowanie ciągów HTML, adresów URL lub całych stron internetowych do plików PDF.
  • Renderowanie obrazów i tekstu – programowe dodawanie nagłówków, stopek, znaków wodnych i obrazów.
  • Łączenie i dzielenie plików PDF – łącz wiele dokumentów lub wyodrębnij konkretne strony.
  • Wypełnianie formularzy i adnotacje – praca z interaktywnymi formularzami PDF.
  • Brak zewnętrznych zależności – działa bez konieczności instalowania programów Adobe Acrobat lub Microsoft Office.

IronPDF obsługuje platformy .NET Framework, .NET Core oraz .NET 6/7+, dzięki czemu idealnie nadaje się zarówno do aplikacji .NET na komputery stacjonarne, jak i aplikacji internetowych.

Instalacja IronPDF za pośrednictwem NuGet

Aby rozpocząć, zainstaluj IronPDF w swoim projekcie za pomocą menedżera pakietów NuGet:

Install-Package IronPdf

Dzięki temu dodane zostaną wszystkie niezbędne odniesienia, dzięki czemu będziesz mógł zacząć korzystać z ChromePdfRenderer, HtmlToPdf i innych zaawansowanych funkcji IronPDF.

W tym przykładzie wykorzystamy aplikację Windows Forms utworzoną w programie Visual Studio, zawierającą przycisk uruchamiający generowanie pliku PDF oraz etykietę wskazującą moment zakończenia procesu.

Wdrażanie BackgroundWorker dla IronPDF

Teraz wykorzystamy poniższe przykłady kodu, aby w uporządkowany i bezpieczny sposób przeanalizować proces korzystania z BackgroundWorker:

Krok 1 – Zdefiniuj BackgroundWorker

Możesz utworzyć i skonfigurować obiekt BackgroundWorker w projektancie lub w kodzie. Oto podejście oparte na kodzie:

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

Spowoduje to zainicjowanie procesu roboczego i skonfigurowanie niezbędnych zdarzeń do wykonania w tle oraz zakończenia.

Krok 2 – Obsługa zdarzenia DoWork

Metoda DoWork działa w innym wątku, wykonując operację w tle (generowanie pliku 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

Uwaga: Nie można tutaj korzystać z elementów interfejsu użytkownika, ponieważ działa on w wątku roboczym.

Krok 3 – Użyj RunWorkerCompleted do powiadomienia o zakończeniu

Po zakończeniu działania wątku w tle można bezpiecznie zaktualizować interfejs użytkownika o wyniki.

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

Krok 4 – Wywołanie BackgroundWorker z interfejsu użytkownika

Dodaj przycisk Start, aby po kliknięciu uruchomić zadanie w tle:

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

Pełny przykład kodu

Oto wszystko połączone w jednym działającym fragmencie kodu 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

Wynik formularza

C# BackgroundWorker (jak to działa dla programistów): Rysunek 2 – Wynik formularza po utworzeniu pliku PDF

Wynik w formacie PDF

C# BackgroundWorker (Jak to działa dla programistów): Rysunek 3 – Wynik w formacie PDF

Najlepsze praktyki

Unikaj dostępu do interfejsu użytkownika w DoWork

Procedura obsługi zdarzeń DoWork działa w innym wątku, więc nie można uzyskać bezpośredniego dostępu do elementów interfejsu użytkownika. Użyj RunWorkerCompleted lub kontroluj wywołania Invoke(), aby zapewnić bezpieczną aktualizację interfejsu użytkownika.

Obsługa asynchronicznego anulowania

Jeśli zadanie jest długie, włącz opcję WorkerSupportsCancellation = true i monitoruj CancellationPending wewnątrz DoWork, aby umożliwić anulowanie zadania na żądanie.

Korzystaj z aktualizacji postępów (opcjonalnie)

Można włączyć opcję WorkerReportsProgress = true i użyć zdarzenia ProgressChanged do wyświetlenia paska postępu lub komunikatów.

Sprawdź poprawność argumentu wejściowego

Podczas korzystania z RunWorkerAsync(argument) należy zweryfikować argument w DoWork i zwrócić wszelkie wyniki metody za pośrednictwem e.Result.

Wnioski

Korzystanie z BackgroundWorker w połączeniu z IronPDF pozwala na wykonywanie wymagających zadań związanych z renderowaniem plików PDF w wątku w tle, dzięki czemu aplikacja pozostaje responsywna. Jest to szczególnie cenne podczas pracy z aplikacjami WinForms lub WPF, które wymagają responsywnych aktualizacji interfejsu użytkownika podczas długotrwałych zadań, takich jak generowanie plików PDF.

Obsługując procedurę obsługi zdarzenia DoWork, monitorując wynik końcowy i bezpiecznie aktualizując interfejs użytkownika w zdarzeniu RunWorkerCompleted, zapewniasz płynne działanie operacji w tle.

Chociaż async/await jest często wybierane do nowych aplikacji, BackgroundWorker pozostaje niezawodnym narzędziem dla starszych projektów lub projektów WinForms. Niezależnie od tego, czy eksportujesz raporty, czy generujesz dokumenty w locie, to podejście pomoże Ci w pełni wykorzystać możliwości IronPDF, jednocześnie zapewniając płynne działanie aplikacji i jej przyjazność dla użytkownika.

Chcesz sam spróbować?

Pobierz bezpłatną wersję próbną IronPDF i już dziś zacznij tworzyć zaawansowane rozwiązania PDF w języku C#. Wersja próbna zapewnia pełny dostęp do funkcji przedstawionych w tym artykule — nie jest wymagana karta kredytowa.

Często Zadawane Pytania

Jak mogę wygenerować plik PDF w aplikacji C# Windows Forms bez zawieszania interfejsu użytkownika?

Można wykorzystać klasę C# BackgroundWorker w połączeniu z IronPDF do generowania plików PDF w oddzielnym wątku. Zapewnia to, że główny wątek interfejsu użytkownika pozostaje responsywny podczas tego procesu.

Jaka jest rola procedury obsługi zdarzeń DoWork w klasie BackgroundWorker?

Obsługa zdarzeń DoWork służy do wykonywania zadań długotrwałych, takich jak generowanie plików PDF przy użyciu IronPDF. Działa ona w oddzielnym wątku od interfejsu użytkownika, zapobiegając zawieszaniu się interfejsu.

Jak mogę zaktualizować interfejs użytkownika wynikami zadania generowania plików PDF w tle?

Użyj zdarzenia RunWorkerCompleted, aby zaktualizować interfejs użytkownika o wyniki generowania pliku PDF. Zdarzenie to jest wyzwalane po zakończeniu zadania w tle, umożliwiając bezpieczną interakcję z elementami interfejsu użytkownika.

Jakie są zalety korzystania z BackgroundWorker do przetwarzania plików PDF w starszych aplikacjach .NET?

BackgroundWorker oferuje prosty sposób na wdrożenie operacji asynchronicznych w starszych aplikacjach WinForms, zapewniając prosty model obsługi zadań, takich jak przetwarzanie plików PDF za pomocą IronPDF, przy jednoczesnym zachowaniu responsywności interfejsu użytkownika.

Czy mogę anulować zadanie generowania pliku PDF za pomocą BackgroundWorker?

Tak, BackgroundWorker obsługuje anulowanie zadań. Anulowanie można zaimplementować, sprawdzając właściwość CancellationPending w procedurze obsługi zdarzenia DoWork i płynnie kończąc zadanie.

Jak mogę śledzić postęp generowania pliku PDF przy użyciu BackgroundWorker?

Możesz zgłaszać postępy z metody DoWork za pomocą metody ReportProgress klasy BackgroundWorker. Pozwala to na aktualizowanie interfejsu użytkownika informacjami o postępach podczas generowania pliku PDF.

Dlaczego należy unikać aktualizacji interfejsu użytkownika w procedurze obsługi zdarzenia DoWork?

Należy unikać aktualizacji interfejsu użytkownika w procedurze obsługi zdarzenia DoWork, ponieważ działa ona w oddzielnym wątku. Bezpośrednia manipulacja interfejsem użytkownika może prowadzić do problemów z wątkami. Zamiast tego do aktualizacji interfejsu użytkownika należy używać zdarzeń RunWorkerCompleted lub ProgressChanged.

Jakie kroki należy wykonać, aby skonfigurować BackgroundWorker do generowania plików PDF w języku C#?

Konfiguracja BackgroundWorker obejmuje zainicjowanie procesu, obsługę zdarzeń DoWork i RunWorkerCompleted oraz uruchomienie zadania za pomocą RunWorkerAsync. Taka konfiguracja służy do wykonywania zadań, takich jak generowanie plików PDF za pomocą IronPDF.

Czy konieczne jest stosowanie nowoczesnych wzorców async/await do generowania plików PDF w aplikacjach .NET?

Chociaż w nowych aplikacjach zaleca się stosowanie nowoczesnych wzorców async/await, BackgroundWorker pozostaje przydatny w starszych aplikacjach WinForms do obsługi zadań asynchronicznych, takich jak generowanie plików PDF za pomocą IronPDF, ze względu na swoją prostotę i łatwość użycia.

Jacob Mellor, Dyrektor Technologiczny @ Team Iron
Dyrektor ds. technologii

Jacob Mellor jest Chief Technology Officer w Iron Software i wizjonerskim inżynierem, pionierem technologii C# PDF. Jako pierwotny deweloper głównej bazy kodowej Iron Software, kształtuje architekturę produktów firmy od jej początku, przekształcając ją wspólnie z CEO Cameron Rimington w firmę liczą...

Czytaj więcej

Zespol wsparcia Iron

Jestesmy online 24 godziny, 5 dni w tygodniu.
Czat
Email
Zadzwon do mnie