Jak generować pliki PDF za pomocą Async & Multithreading w C
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.
-
Install IronPDF with NuGet Package Manager
PM > Install-Package IronPdf -
Skopiuj i uruchom ten fragment kodu.
var pdf = await IronPdf.ChromePdfRenderer.RenderHtmlAsPdfAsync("<h1>Hello World!</h1>"); -
Wdrożenie do testowania w środowisku produkcyjnym
Rozpocznij używanie IronPDF w swoim projekcie już dziś z darmową wersją próbną
Minimalny proces (5 kroków)
- Pobierz IronPDF z NuGet do asynchronicznej i wielowątkowej generacji PDF
- Przygotuj treść HTML do konwersji
- Użyj metody
RenderHtmlAsPdfAsyncdo asynchronicznej konwersji HTML na PDF - Poznaj metodę
Parallel.ForEachdo wielowątkowości w przetwarzaniu PDF - Przeglądaj porównanie wydajności różnych technik generacji PDF
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);
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
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
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
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
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.

