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.

Dzięki metodzie RenderHtmlAsPdfAsync można efektywnie konwertować treści HTML do formatu 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 obsługuje operacje asynchroniczne przy użyciu metod renderowania, 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. Dla pełnej dokumentacji metod, zobacz dokumentację metod renderowania.

Asynchroniczna generacja PDF zapobiega zamrażaniu interfejsu użytkownika w aplikacjach desktopowych i poprawia przepustowość żądań w aplikacjach internetowych. Zastosowanie wzorców await pozwala aplikacji na obsługę innych operacji w trakcie oczekiwania na zakończenie renderowania pliku PDF, co znacznie poprawia responsywność i komfort użytkowania.

Dłączego 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 generowania wielu plików PDF, wdrażanie 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 używać bloków catch, wdrożyć logikę ponawiania prób w przypadku przejściowych błędów oraz rozważyć użycie Polly w przypadku 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 dla wątków i obsługuje wielowątkowość przy użyciu silnika renderującego ChromePdfRenderer. Należy pamiętać, że wielowątkowość jest ograniczona na komputerach z systemem macOS. Silnik renderujący Chrome zapewnia doskonałą bezpieczeństwo wątków i wydajność w przypadku operacji wykonywanych równolegle.

Wzorzec Parallel.ForEach sprawdza się dobrze w przetwarzaniu plików PDF w trybie wsadowym, 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 systemówych. 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 firmy IronPDF został zaprojektowany jako bezpieczny dla wątków, ale należy wziąć pod uwagę pewne kwestie. Podczas korzystania z ustawień niestandardowych należy utworzyć oddzielne instancje renderera dla każdego wątku, unikać współdzielenia instancji PdfDocument między wątkami bez synchronizacji oraz monitorować zużycie pamięci podczas równoczesnego przetwarzania dużych dokumentów. 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 powinienem 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 dla operacji obciążających procesor, ograniczenie do 2–4 wątków w przypadku plików PDF wymagających dużej ilości pamięci oraz monitorowanie zasobów systemowych w celu znalezienia optymalnej konfiguracji. Przykłady asynchroniczne ilustrują różne strategie wątkowania.

Jakich ulepszeń wydajności mogę 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.

Dłączego 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 mogę zmierzyć wydajność mojej aplikacji?

Pomiar wydajności generowania plików PDF wymaga odpowiedniego testowania porównawczego i monitorowania. Użyj System.Diagnostics.Stopwatch do dokładnych pomiarów czasu, wdroż niestandardowe liczniki wydajności do monitorowania produkcji i wykorzystaj Application Insights lub podobne narzędzia APM. 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 systemówe, 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

Ile poprawy wydajności mogę oczekiwać przy asynchronicznym generowaniu PDF?

Asynchroniczne operacje i wielowątkowość IronPDF mogą skrócić czas przetwarzania wsadowego do 65% w porównaniu do metod synchronicznych, zwłaszcza podczas renderowania złożonych treści HTML. Faktyczny zysk wydajności zależy od czynników takich jak złożoność HTML, zasoby systemowe i liczba równoczesnych operacji.

Jaki jest najprostszy sposób na asynchroniczną konwersję HTML do PDF?

Najprostszy sposób to użycie metody RenderHtmlAsPdfAsync IronPDF. Za pomocą jednego wiersza kodu: `var pdf = await IronPdf.ChromePdfRenderer.RenderHtmlAsPdfAsync("Hello World!");`, możesz efektywnie konwertować zawartość HTML na PDF, zachowując responsywność aplikacji.

Dlaczego powinienem używać metod asynchronicznych zamiast synchronicznego generowania PDF?

Metody asynchroniczne w IronPDF zapobiegają zamarzaniu interfejsu użytkownika w aplikacjach desktopowych, poprawiają przepustowość żądań w aplikacjach internetowych, umożliwiają lepsze wykorzystanie zasobów w procesorach wielordzeniowych oraz zwiększają skalowalność w środowiskach serwerowych. Są szczególnie korzystne podczas obsługi złożonych konwersji HTML do PDF lub przetwarzania wielu żądań PDF jednocześnie.

Jakiego wzorca asynchronicznego biblioteka używa do operacji PDF?

IronPDF wdraża wzorzec asynchroniczny oparty na zadaniach (TAP) dla swoich operacji asynchronicznych, w tym metody takie jak RenderHtmlAsPdfAsync. Wzorzec ten umożliwia nieblokujące operacje generowania PDF i integruje się bezproblemowo z asynchronicznymi słowami kluczowymi C#.

Jak mogę przetwarzać wiele plików PDF równolegle dla lepszej wydajności?

IronPDF obsługuje przetwarzanie wsadowe za pomocą wzorców takich jak Task.WhenAll do równoległego wykonywania wielu generacji PDF, Parallel.ForEach do wielowątkowości w przetwarzaniu PDF oraz wzorców producent-konsument z kanałami do dużych partii. Te podejścia optymalizują wykorzystanie zasobów i znacząco skracają całkowity czas przetwarzania.

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,926,724 | Wersja: 2026.5 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.