フッターコンテンツにスキップ
.NETヘルプ

C# BackgroundWorker(開発者向けの仕組み)

IronPDFを使用してPDFを生成することは、.NET開発者にとって一般的な作業です。特に動的なレポート、請求書、またはドキュメント自動化システムを構築する際において。 しかし、Windows FormsまたはWPFアプリでメインUIスレッドでPDF生成をトリガーしたことがあるなら、ユーザーインターフェースがフリーズしたり、応答しなくなるのを見たことがあるでしょう。特に大きなHTMLコンテンツをレンダリングする場合や複雑なPDFレイアウトを処理する場合は特にそうです。

そこで、C#のBackgroundWorkerクラスが登場します。 この記事では、デスクトップアプリでの非同期操作をUIをロックせずに処理するために、BackgroundWorkerとIronPDFを統合する方法について説明します。

IronPDFでBackgroundWorkerを使用する理由

UIを応答性のある状態に保つ

PDF生成のようなCPU集約型またはI/Oに制約されるタスクをメインスレッドで実行すると、UIがロックされます。 ユーザーは操作が進行中の間、クリック、ドラッグ、アプリケーションとのインタラクションができません。 BackgroundWorkerオブジェクトを使用することで、作業を別のスレッドに移動し、バックグラウンド処理中でもインターフェースが迅速で使いやすい状態を維持できます。

レポート生成や長時間実行タスクに最適

アプリがデータのエクスポート、HTMLをPDFに変換、詳細レポートのレンダリングを含む場合、それをバックグラウンドワーカーにオフロードすることで、アプリケーションはよりプロフェッショナルでパフォーマンスが向上します。

レガシーWinFormsアプリとも互換性あり

モダンアプリはしばしばasync/awaitを使用しますが、多くの古いプロジェクトはそのシンプルさとVisual Studioでのデザイン時のサポートのためにBackgroundWorkerを利用するメリットがあります。

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で返します。

結論

BackgroundWorkerとIronPDFを使用することで、バックグラウンドスレッドで大規模なPDFレンダリングタスクを実行し、アプリケーションをレスポンシブに保つことができます。これは特に、PDF生成のような長時間実行されるタスクの間にレスポンシブなUIアップデートを必要とするWinFormsまたはWPFアプリで価値があります。

doworkイベントハンドラーを処理し、最終結果を監視し、runworkercompletedイベントでユーザーインターフェースを安全に更新することで、バックグラウンド操作をスムーズに実行することができます。

新しいアプリケーションのためのgo-toはしばしばasync/awaitですが、BackgroundWorkerはレガシーまたはWinFormsプロジェクトにとって信頼性の高いツールです。 レポートをエクスポートする場合でも、オフハンドでドキュメントを生成する場合でも、このアプローチは、アプリをスムーズでユーザーフレンドリーに保ちながら、IronPDFを最大限に活用するのに役立ちます。

準備はできましたか?

無料のIronPDFトライアルをダウンロードして、今日からC#で強力なPDFソリューションの構築を始めましょう。 トライアルでは、この記事で紹介された機能に完全にアクセスでき、クレジットカードの必要はありません。

よくある質問

C# Windows FormsアプリケーションでUIをフリーズさせずにPDF生成を行うにはどうすればよいですか?

C# BackgroundWorkerクラスをIronPDFと組み合わせて使用し、別のスレッドでPDF生成を行うことができます。これにより、プロセス中にメインUIスレッドがレスポンシブに保たれます。

BackgroundWorkerのDoWorkイベントハンドラーの役割は何ですか?

DoWorkイベントハンドラーは、IronPDFを使用したPDF生成のような長時間のタスクを実行する場所です。UIとは別のスレッドで実行されるため、インターフェースがフリーズするのを防ぎます。

背景のPDF生成タスクの結果でUIを更新するにはどうすればよいですか?

RunWorkerCompletedイベントを使用して、PDF生成の結果でUIを更新します。このイベントはバックグラウンドタスクが完了したときにトリガーされ、UI要素との安全なインタラクションを可能にします。

古い.NETアプリケーションでのPDF処理にBackgroundWorkerを使用する利点は何ですか?

BackgroundWorkerは、レガシーなWinFormsアプリケーションで非同期操作を実装するための簡単な方法を提供し、IronPDFでのPDF処理のようなタスクを扱うシンプルなモデルを提供しながら、UIをレスポンシブに保ちます。

BackgroundWorkerを使用してPDF生成タスクをキャンセルできますか?

はい、BackgroundWorkerはタスクのキャンセルをサポートしています。DoWorkイベントハンドラーでCancellationPendingプロパティを確認し、タスクを円滑に終了させることでキャンセルを実装できます。

BackgroundWorkerを使用してPDF生成の進行状況を追跡するにはどうすればよいですか?

BackgroundWorkerのReportProgressメソッドを使用して、DoWorkメソッドから進行状況を報告できます。これにより、PDF生成中にUIに進行状況情報を更新できます。

なぜDoWorkイベントハンドラーでUIの更新を避けるべきなのですか?

DoWorkイベントハンドラーでのUIの更新は避けるべきです。それが別のスレッドで実行されるからです。直接のUI操作はスレッド問題を引き起こす可能性があります。代わりに、UIの更新にはRunWorkerCompletedまたはProgressChangedイベントを使用してください。

C#でPDF生成のためのBackgroundWorkerの設定にはどのような手順が含まれていますか?

BackgroundWorkerの設定には、ワーカーの初期化、DoWorkおよびRunWorkerCompletedイベントの処理、RunWorkerAsyncを使用したタスクの開始が含まれています。この設定は、IronPDFを使ったPDF生成のようなタスクを実行するために使用されます。

非同期/待機パターンを使用して.NETアプリケーションでPDF生成を行うことは必要ですか?

最新の非同期/待機パターンは新しいアプリケーションに推奨されますが、古いWinFormsアプリケーションでは、BackgroundWorkerがPDF生成のような非同期タスクを処理するためにそのシンプルさと使いやすさから有用なままです。

Curtis Chau
テクニカルライター

Curtis Chauは、カールトン大学でコンピュータサイエンスの学士号を取得し、Node.js、TypeScript、JavaScript、およびReactに精通したフロントエンド開発を専門としています。直感的で美しいユーザーインターフェースを作成することに情熱を持ち、Curtisは現代のフレームワークを用いた開発や、構造の良い視覚的に魅力的なマニュアルの作成を楽しんでいます。

開発以外にも、CurtisはIoT(Internet of Things)への強い関心を持ち、ハードウェアとソフトウェアの統合方法を模索しています。余暇には、ゲームをしたりDiscordボットを作成したりして、技術に対する愛情と創造性を組み合わせています。