Jak generować pliki PDF przy użyciu asynchroniczności i wielowątkowości

Jak generować pliki PDF za pomocą Async & Multithreading w C

This article was translated from English: Does it need improvement?
Translated
View the article in English

IronPDF umożliwia wysokowydajną generację plików PDF w C# z użyciem operacji asynchronicznych i wielowątkowości, skracając czas przetwarzania wsadowego nawet o 65% w porównaniu z metodami synchronicznymi dla złożonych scenariuszy renderowania HTML.

Szybki start: Asynchroniczna konwersja HTML do PDF z IronPDF

Rozpocznij tworzenie asynchronicznej generacji PDF za pomocą IronPDF zaledwie w kilku linijkach kodu.

Z metodą RenderHtmlAsPdfAsync można efektywnie konwertować treści HTML na PDF, optymalizując wydajność aplikacji. Ten przewodnik pokazuje, jak wykorzystać operacje asynchroniczne do wysokowydajnej generacji PDF, idealnej do przetwarzania wsadowego i w środowiskach wielowątkowych.

  1. Install IronPDF with NuGet Package Manager

    PM > Install-Package IronPdf
  2. Skopiuj i uruchom ten fragment kodu.

    var pdf = await IronPdf.ChromePdfRenderer.RenderHtmlAsPdfAsync("<h1>Hello World!</h1>");
  3. Wdrożenie do testowania w środowisku produkcyjnym

    Rozpocznij używanie IronPDF w swoim projekcie już dziś z darmową wersją próbną

    arrow pointer


Jak wdrożyć asynchroniczną generację PDF w C#?

IronPDF w pełni wspiera operacje asynchroniczne z użyciem metod renderujących, takich jak RenderHtmlAsPdfAsync. Asynchroniczna implementacja w IronPDF wykorzystuje asynchroniczny wzorzec oparty na zadaniach (TAP) do umożliwienia nieblokujących operacji generowania PDF. Takie podejście jest korzystne przy renderowaniu złożonych treści HTML lub przetwarzaniu równoczesnych żądań PDF.

Asynchroniczna generacja PDF zapobiega zamrażaniu interfejsu użytkownika w aplikacjach desktopowych i poprawia przepustowość żądań w aplikacjach internetowych. Użycie wzorców await umożliwia aplikacji obsługę innych operacji podczas oczekiwania na zakończenie renderowania PDF, znacznie poprawiając responsywność i doświadczenie użytkownika.

Dlaczego warto używać metod asynchronicznych do generacji PDF?

Metody asynchroniczne zapewniają kluczowe zalety dla przepływów pracy generacji PDF. Zapewniają one responsywność aplikacji podczas operacji wymagających dużej ilości zasobów, umożliwiają lepsze wykorzystanie zasobów na procesorach wielordzeniowych oraz poprawiają skalowalność w środowiskach serwerowych. Podczas przetwarzania złożonych konwersji HTML do PDF operacje asynchroniczne zapobiegają problemom z przekroczeniem limitu czasu i poprawiają komfort użytkowania.

:path=/static-assets/pdf/content-code-examples/how-to/async-async.cs
using IronPdf;
using System.Threading.Tasks;

// Instantiate ChromePdfRenderer
ChromePdfRenderer renderer = new ChromePdfRenderer();

string[] htmlStrings = {"<h1>Html 1</h1>", "<h1>Html 2</h1>", "<h1>Html 3</h1>"};

// Create an array to store the tasks for rendering
var renderingTasks = new Task<PdfDocument>[htmlStrings.Length];

for (int i = 0; i < htmlStrings.Length; i++)
{
    int index = i; // Capturing the loop variable
    renderingTasks[i] = Task.Run(async () =>
    {
        // Render HTML to PDF
        return await renderer.RenderHtmlAsPdfAsync(htmlStrings[index]);
    });
}

// Wait for all rendering tasks to complete
// await Task.WhenAll(renderingTasks);
Imports IronPdf
Imports System.Threading.Tasks

' Instantiate ChromePdfRenderer
Private renderer As New ChromePdfRenderer()

Private htmlStrings() As String = {"<h1>Html 1</h1>", "<h1>Html 2</h1>", "<h1>Html 3</h1>"}

' Create an array to store the tasks for rendering
Private renderingTasks = New Task(Of PdfDocument)(htmlStrings.Length - 1){}

For i As Integer = 0 To htmlStrings.Length - 1
	Dim index As Integer = i ' Capturing the loop variable
	renderingTasks(i) = Task.Run(Async Function()
		' Render HTML to PDF
		Return Await renderer.RenderHtmlAsPdfAsync(htmlStrings(index))
	End Function)
Next i

' Wait for all rendering tasks to complete
' await Task.WhenAll(renderingTasks);
$vbLabelText   $csharpLabel

Jakie są typowe wzorce przetwarzania wsadowego?

Przetwarzanie plików PDF w trybie wsadowym wymaga starannego rozważenia kwestii wykorzystania pamięci i wydajności. Skuteczne wzorce obejmują użycie Task.WhenAll do równoległego wykonania wielu generacji PDF, wdrożenie wzorców producent-konsument z kanałami dla dużych partii oraz wykorzystanie przykładów przetwarzania równoległego z dokumentacji IronPDF.

// Batch processing with progress tracking
public async Task<List<PdfDocument>> ProcessBatchAsync(List<string> htmlContents, IProgress<int> progress)
{
    var renderer = new ChromePdfRenderer();
    var results = new List<PdfDocument>();
    var completed = 0;

    var tasks = htmlContents.Select(async html => {
        var pdf = await renderer.RenderHtmlAsPdfAsync(html);
        Interlocked.Increment(ref completed);
        progress?.Report(completed);
        return pdf;
    });

    results.AddRange(await Task.WhenAll(tasks));
    return results;
}
// Batch processing with progress tracking
public async Task<List<PdfDocument>> ProcessBatchAsync(List<string> htmlContents, IProgress<int> progress)
{
    var renderer = new ChromePdfRenderer();
    var results = new List<PdfDocument>();
    var completed = 0;

    var tasks = htmlContents.Select(async html => {
        var pdf = await renderer.RenderHtmlAsPdfAsync(html);
        Interlocked.Increment(ref completed);
        progress?.Report(completed);
        return pdf;
    });

    results.AddRange(await Task.WhenAll(tasks));
    return results;
}
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks

' Batch processing with progress tracking
Public Async Function ProcessBatchAsync(htmlContents As List(Of String), progress As IProgress(Of Integer)) As Task(Of List(Of PdfDocument))
    Dim renderer As New ChromePdfRenderer()
    Dim results As New List(Of PdfDocument)()
    Dim completed As Integer = 0

    Dim tasks = htmlContents.Select(Async Function(html)
                                        Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)
                                        Interlocked.Increment(completed)
                                        progress?.Report(completed)
                                        Return pdf
                                    End Function)

    results.AddRange(Await Task.WhenAll(tasks))
    Return results
End Function
$vbLabelText   $csharpLabel

Jak radzić sobie z błędami w asynchronicznych operacjach na plikach PDF?

Obsługa błędów w asynchronicznych operacjach na plikach PDF wymaga kompleksowych strategii zarządzania wyjątkami. W metodach asynchronicznych należy stosować bloki try-catch, wdrażać logikę ponawiania prób w przypadku przejściowych błędów oraz rozważyć użycie biblioteki Polly do zaawansowanych zasad ponawiania prób. W celu szczegółowego rozwiązywania problemów związanych z wydajnością IronPDF zapewnia rozbudowane możliwości rejestrowania.

public async Task<PdfDocument> RenderWithRetryAsync(string html, int maxRetries = 3)
{
    var renderer = new ChromePdfRenderer();

    for (int i = 0; i < maxRetries; i++)
    {
        try
        {
            return await renderer.RenderHtmlAsPdfAsync(html);
        }
        catch (Exception ex) when (i < maxRetries - 1)
        {
            // Log the exception
            await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, i))); // Exponential backoff
        }
    }

    throw new InvalidOperationException("Failed to render PDF after maximum retries");
}
public async Task<PdfDocument> RenderWithRetryAsync(string html, int maxRetries = 3)
{
    var renderer = new ChromePdfRenderer();

    for (int i = 0; i < maxRetries; i++)
    {
        try
        {
            return await renderer.RenderHtmlAsPdfAsync(html);
        }
        catch (Exception ex) when (i < maxRetries - 1)
        {
            // Log the exception
            await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, i))); // Exponential backoff
        }
    }

    throw new InvalidOperationException("Failed to render PDF after maximum retries");
}
Imports System
Imports System.Threading.Tasks

Public Class PdfRenderer
    Public Async Function RenderWithRetryAsync(html As String, Optional maxRetries As Integer = 3) As Task(Of PdfDocument)
        Dim renderer As New ChromePdfRenderer()

        For i As Integer = 0 To maxRetries - 1
            Try
                Return Await renderer.RenderHtmlAsPdfAsync(html)
            Catch ex As Exception When i < maxRetries - 1
                ' Log the exception
                Await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, i))) ' Exponential backoff
            End Try
        Next

        Throw New InvalidOperationException("Failed to render PDF after maximum retries")
    End Function
End Class
$vbLabelText   $csharpLabel

Jak mogę wykorzystać wielowątkowość do generowania plików PDF?

IronPDF jest bezpieczny w wątkach i wspiera wielowątkowość podczas używania silnika renderowania ChromePdfRenderer. Należy pamiętać, że wielowątkowość jest ograniczona na komputerach z macOS. Silnik renderujący Chrome zapewnia doskonałą bezpieczeństwo wątków i wydajność w przypadku operacji wykonywanych równolegle.

Wzorzec Parallel.ForEach dobrze sprawdza się przy wsadowym przetwarzaniu PDF-ów, umożliwiając efektywne wykorzystanie wszystkich dostępnych rdzeni procesora. Aby zapoznać się z wyczerpującymi przykładami generowania wielowątkowego, należy zapoznać się z dokumentacją IronPDF.

Kiedy należy wybrać wielowątkowość zamiast asynchroniczności?

Wielowątkowość jest idealnym rozwiązaniem w przypadku operacji obciążających procesor, gdzie konieczne jest jednoczesne przetwarzanie wielu plików PDF przy wystarczających zasobach systemowych. Wybierz wielowątkowość podczas przetwarzania dużych partii plików PDF na systemach wielordzeniowych, gdy generowanie każdego pliku PDF jest niezależne i gdy można kontrolować zużycie pamięci. Async jest lepszym rozwiązaniem w przypadku operacji ograniczonych przez operacje wejścia/wyjścia oraz w celu zachowania responsywności aplikacji.

Jakie są kwestie związane z bezpieczeństwem wątków?

ChromePdfRenderer IronPDF jest zaprojektowany z myślą o bezpieczeństwie wątków, ale obowiązują pewne uwagi. Twórz oddzielne instancje rendererów dla każdego wątku przy użyciu ustawień niestandardowych, unikaj dzielenia instancji PdfDocument pomiędzy wątkami bez synchronizacji i monitoruj zużycie pamięci podczas przetwarzania dużych dokumentów jednocześnie. Przegląd instalacji zawiera dodatkowe informacje na temat konfiguracji IronPDF w celu zapewnienia optymalnego bezpieczeństwa wątków.

// Thread-safe PDF generation with custom settings per thread
public void ProcessPdfsInParallel(List<string> htmlContents)
{
    Parallel.ForEach(htmlContents, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, 
        html =>
        {
            // Create a new renderer instance for each thread
            var renderer = new ChromePdfRenderer
            {
                RenderingOptions = new ChromePdfRenderOptions
                {
                    MarginTop = 10,
                    MarginBottom = 10,
                    PaperSize = IronPdf.Rendering.PdfPaperSize.A4
                }
            };

            var pdf = renderer.RenderHtmlAsPdf(html);
            pdf.SaveAs($"output_{Thread.CurrentThread.ManagedThreadId}_{DateTime.Now.Ticks}.pdf");
        });
}
// Thread-safe PDF generation with custom settings per thread
public void ProcessPdfsInParallel(List<string> htmlContents)
{
    Parallel.ForEach(htmlContents, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, 
        html =>
        {
            // Create a new renderer instance for each thread
            var renderer = new ChromePdfRenderer
            {
                RenderingOptions = new ChromePdfRenderOptions
                {
                    MarginTop = 10,
                    MarginBottom = 10,
                    PaperSize = IronPdf.Rendering.PdfPaperSize.A4
                }
            };

            var pdf = renderer.RenderHtmlAsPdf(html);
            pdf.SaveAs($"output_{Thread.CurrentThread.ManagedThreadId}_{DateTime.Now.Ticks}.pdf");
        });
}
Imports System
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks
Imports IronPdf

' Thread-safe PDF generation with custom settings per thread
Public Sub ProcessPdfsInParallel(htmlContents As List(Of String))
    Parallel.ForEach(htmlContents, New ParallelOptions With {.MaxDegreeOfParallelism = Environment.ProcessorCount},
        Sub(html)
            ' Create a new renderer instance for each thread
            Dim renderer = New ChromePdfRenderer With {
                .RenderingOptions = New ChromePdfRenderOptions With {
                    .MarginTop = 10,
                    .MarginBottom = 10,
                    .PaperSize = IronPdf.Rendering.PdfPaperSize.A4
                }
            }

            Dim pdf = renderer.RenderHtmlAsPdf(html)
            pdf.SaveAs($"output_{Thread.CurrentThread.ManagedThreadId}_{DateTime.Now.Ticks}.pdf")
        End Sub)
End Sub
$vbLabelText   $csharpLabel

Ile wątków równoległych należy używać?

Optymalna liczba współbieżnych wątków zależy od rdzeni procesora, dostępnej pamięci i złożoności pliku PDF. Ogólne wytyczne obejmują użycie Environment.ProcessorCount do operacji obciążających CPU, ograniczanie liczby wątków do 2-4 dla pamięciożernych plików PDF oraz monitorowanie zasobów systemowych w celu znalezienia optymalnej konfiguracji. Przykłady asynchroniczne ilustrują różne strategie wątkowania.

Jakich ulepszeń wydajności można się spodziewać?

Porównanie pokazuje znaczące różnice w wydajności między poszczególnymi metodami renderowania. W renderowaniu dodano 5-sekundowe opóźnienie za pomocą klasy WaitFor w celu symulacji złożonego renderowania HTML. Poniżej znajduje się tabela porównawcza wydajności przy użyciu różnych technik opisanych powyżej.

Dlaczego asynchroniczność działa lepiej niż synchroniczność?

Normalne renderowanie Renderowanie asynchroniczne Renderowanie wielowątkowe
15,75 sekundy 05,59 sekundy 05,68 sekundy

Operacje asynchroniczne wyróżniają się, ponieważ umożliwiają efektywne zarządzanie zasobami puli wątków, zapobiegają blokowaniu głównego wątku i pozwalają na lepsze wykorzystanie procesora podczas operacji wejścia/wyjścia. Poprawa wydajności wynika z jednoczesnego uruchamiania wielu operacji renderowania zamiast czekania na sekwencyjne zakończenie każdej z nich.

Jak mierzyć wydajność aplikacji?

Pomiar wydajności generowania plików PDF wymaga odpowiedniego testowania porównawczego i monitorowania. Należy użyć System.Diagnostics.Stopwatch do dokładnych pomiarów czasu, wdrożyć niestandardowe liczniki wydajności do monitorowania produkcji i korzystać z narzędzi APM, takich jak Application Insights. Warto rozważyć wykorzystanie przykładów z przewodnika szybkiego startu jako punktu odniesienia do testów wydajności.

public async Task<PerformanceMetrics> MeasurePerformanceAsync(string html, int iterations)
{
    var metrics = new PerformanceMetrics();
    var renderer = new ChromePdfRenderer();
    var stopwatch = new Stopwatch();

    // Warm-up run
    await renderer.RenderHtmlAsPdfAsync(html);

    for (int i = 0; i < iterations; i++)
    {
        stopwatch.Restart();
        await renderer.RenderHtmlAsPdfAsync(html);
        stopwatch.Stop();

        metrics.AddMeasurement(stopwatch.ElapsedMilliseconds);
    }

    return metrics;
}
public async Task<PerformanceMetrics> MeasurePerformanceAsync(string html, int iterations)
{
    var metrics = new PerformanceMetrics();
    var renderer = new ChromePdfRenderer();
    var stopwatch = new Stopwatch();

    // Warm-up run
    await renderer.RenderHtmlAsPdfAsync(html);

    for (int i = 0; i < iterations; i++)
    {
        stopwatch.Restart();
        await renderer.RenderHtmlAsPdfAsync(html);
        stopwatch.Stop();

        metrics.AddMeasurement(stopwatch.ElapsedMilliseconds);
    }

    return metrics;
}
Imports System.Diagnostics
Imports System.Threading.Tasks

Public Class PerformanceMetrics
    ' Assume this class has an AddMeasurement method
    Public Sub AddMeasurement(milliseconds As Long)
        ' Implementation here
    End Sub
End Class

Public Class ChromePdfRenderer
    ' Assume this class has a RenderHtmlAsPdfAsync method
    Public Async Function RenderHtmlAsPdfAsync(html As String) As Task
        ' Implementation here
    End Function
End Class

Public Class PerformanceTester
    Public Async Function MeasurePerformanceAsync(html As String, iterations As Integer) As Task(Of PerformanceMetrics)
        Dim metrics As New PerformanceMetrics()
        Dim renderer As New ChromePdfRenderer()
        Dim stopwatch As New Stopwatch()

        ' Warm-up run
        Await renderer.RenderHtmlAsPdfAsync(html)

        For i As Integer = 0 To iterations - 1
            stopwatch.Restart()
            Await renderer.RenderHtmlAsPdfAsync(html)
            stopwatch.Stop()

            metrics.AddMeasurement(stopwatch.ElapsedMilliseconds)
        Next

        Return metrics
    End Function
End Class
$vbLabelText   $csharpLabel

Jakie czynniki wpływają na szybkość generowania plików PDF?

Na wydajność generowania plików PDF wpływa kilka czynników. Złożoność kodu HTML, w tym wykonywanie kodu JavaScript i renderowanie CSS, ma bezpośredni wpływ na czas przetwarzania. Ładowanie zasobów zewnętrznych, takich jak obrazy i czcionki, może powodować opóźnienia. Kluczową rolę odgrywają zasoby systemowe, takie jak procesor, pamięć i operacje wejścia/wyjścia na dysku. Na szybkość ma również wpływ konfiguracja IronPDF, w tym opcje renderowania i ustawienia silnika. Zrozumienie tych czynników pomaga zoptymalizować proces generowania plików PDF w celu uzyskania maksymalnej wydajności.

W przypadku złożonych scenariuszy wymagających intensywnego wykorzystania JavaScriptu lub opóźnionego renderowania warto rozważyć użycie mechanizmów WaitFor, aby zapewnić pełne wyrenderowanie strony przed wygenerowaniem pliku PDF. Takie podejście gwarantuje dokładny wynik przy zachowaniu przewidywalnych parametrów wydajności.

Często Zadawane Pytania

How much performance improvement can I expect with async PDF generation?

IronPDF's async operations and multithreading can reduce batch processing time by up to 65% compared to synchronous methods, particularly when rendering complex HTML content. The actual performance gain depends on factors like HTML complexity, system resources, and the number of concurrent operations.

What is the simplest way to convert HTML to PDF asynchronously?

The simplest way is using IronPDF's RenderHtmlAsPdfAsync method. With just one line of code: `var pdf = await IronPdf.ChromePdfRenderer.RenderHtmlAsPdfAsync("Hello World!");`, you can efficiently convert HTML content to PDF while maintaining application responsiveness.

Why should I use async methods instead of synchronous PDF generation?

Async methods in IronPDF prevent UI freezing in desktop applications, improve request throughput in web applications, enable better resource utilization on multi-core processors, and enhance scalability in server environments. They're particularly beneficial when handling complex HTML to PDF conversions or processing multiple PDF requests simultaneously.

What async pattern does the library use for PDF operations?

IronPDF implements the Task-based Asynchronous Pattern (TAP) for its async operations, including methods like RenderHtmlAsPdfAsync. This pattern enables non-blocking PDF generation operations and integrates seamlessly with C#'s async/await keywords.

How can I process multiple PDFs in parallel for better performance?

IronPDF supports batch processing using patterns like Task.WhenAll for parallel execution of multiple PDF generations, Parallel.ForEach for multithreading in PDF processing, and producer-consumer patterns with channels for large batches. These approaches optimize resource usage and significantly reduce total processing time.

Chipego
Inżynier oprogramowania
Chipego ma naturalną umiejętność słuchania, która pomaga mu zrozumieć problemy klientów i oferować inteligentne rozwiązania. Dołączył do zespołu Iron Software w 2023 roku, po ukończeniu licencjatu z technologii informatycznej. IronPDF i IronOCR to dwa produkty, na których Chipego się skupia, ale jego ...
Czytaj więcej
Gotowy, aby rozpocząć?
Nuget Pliki do pobrania 18,135,201 | Wersja: 2026.4 just released
Still Scrolling Icon

Wciąż przewijasz?

Czy chcesz szybko dowodu? PM > Install-Package IronPdf
Uruchom przykład i zobacz, jak Twój kod HTML zamienia się w plik PDF.