C# ConfigureAwait(對開發者如何理解的工作)
身為開發人員,異步程式設計是非常有益的,它可以改善您應用程式的效能、效率和反應能力,尤其是那些需要花費大量時間才能完成的作業。 使用 ConfigureAwait(false),可以避免某些情況下的死鎖。 死鎖發生在異步程式設計中,當同步上下文(例如桌面應用程式中的 UI 線程)期望操作完成後才繼續進行。 不過,等待的任務仍在等待同步上下文可用,形成循環等待。
今天,我們將探討 ConfigureAwait 如何與 IronPDF 搭配使用,透過異步程式設計有效率地執行 PDF 處理任務。 IronPDF 是一個 .NET PDF 函式庫,讓處理 PDF 相關工作變得輕而易舉。 憑藉強大的功能、強大的跨平台相容性以及廣泛的說明文件,它是您開發人員工具包中不可或缺的強大 PDF 工具。
瞭解 C# 中的異步程式設計
什麼是異步程式設計?
異步程式設計指的是一種編寫程式碼的方法,允許某些作業獨立於主應用程式線程執行。 這對需要等待的長時間執行任務非常有用,例如 I/O 作業。 透過允許這些任務在不阻塞主線程的情況下執行,應用程式可以在這些任務需要時間完成時繼續執行,最終改善應用程式的效能與反應能力。
異步程式碼中 ConfigureAwait 的作用
ConfigureAwait是異步程式設計中的一種方法,用來控制延續的執行方式。 延續程式碼是在 await 表達式之後執行的程式碼。預設情況下,await 會捕獲目前上下文並嘗試將延續程式碼編組回該上下文,但這可能無效。 ConfigureAwait 可讓您指定延續程式碼是否應在擷取的上下文上執行(如 ConfigureAwait(true) 所示),或不執行(如 ConfigureAwait(false) 所示)。
使用 ConfigureAwait(false) 有助於避免死鎖,因為當你使用它時,你正在告訴任務不要捕獲當前的同步上下文,也不要嘗試在原始上下文上恢復。 然後,這將允許續程在線程池的線程上執行,而非在原始上下文中執行,因此可避免主線程阻塞。
ConfigureAwait(false) 在庫程式碼中或不需要恢復原始上下文的情況下特別有用,從而確保程式碼保持靈活且無死鎖。
如何將 ConfigureAwait 與 IronPDF 搭配使用。
在您的 .NET 專案中設定 IronPDF。
要開始在您的 .NET 專案中使用 IronPDF,請先安裝 IronPDF NuGet 套件。 您可以導覽至工具 > NuGet Package Manager > NuGet Package Manager for Solution,然後搜尋 IronPDF:

或者,在套件管理員控制台執行以下指令:
Install-Package IronPdf
若要開始在程式碼中使用 IronPDF,請確保已將 using IronPdf; 語句放在程式碼檔案的頂部。有關在您的環境中設定 IronPDF 的更詳細指南,請查看其入門頁面。
使用 IronPDF 異步生成 PDFs
異步產生 PDF 檔案對於需要產生大量 PDF 檔案或想要同時執行多個作業的情況特別有利。 使用 IronPDF,您可以異步執行 PDF 相關任務,這可能類似於以下的異步程式碼:
using IronPdf;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
await GeneratePdfAsync();
}
static async Task GeneratePdfAsync()
{
// Create a new instance of ChromePdfRenderer.
ChromePdfRenderer renderer = new ChromePdfRenderer();
// Example HTML content to be converted into a PDF.
string htmlContent = "<h1>Hello World!</h1>";
// Asynchronously render the HTML content as a PDF document.
PdfDocument pdf = await renderer.RenderHtmlAsPdfAsync(htmlContent);
// Asynchronously save the PDF document to a file.
await Task.Run(() => pdf.SaveAs("outputAsync.pdf"));
Console.WriteLine("Working!");
}
}
using IronPdf;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
await GeneratePdfAsync();
}
static async Task GeneratePdfAsync()
{
// Create a new instance of ChromePdfRenderer.
ChromePdfRenderer renderer = new ChromePdfRenderer();
// Example HTML content to be converted into a PDF.
string htmlContent = "<h1>Hello World!</h1>";
// Asynchronously render the HTML content as a PDF document.
PdfDocument pdf = await renderer.RenderHtmlAsPdfAsync(htmlContent);
// Asynchronously save the PDF document to a file.
await Task.Run(() => pdf.SaveAs("outputAsync.pdf"));
Console.WriteLine("Working!");
}
}
Imports IronPdf
Imports System.Threading.Tasks
Friend Class Program
Shared Async Function Main(ByVal args() As String) As Task
Await GeneratePdfAsync()
End Function
Private Shared Async Function GeneratePdfAsync() As Task
' Create a new instance of ChromePdfRenderer.
Dim renderer As New ChromePdfRenderer()
' Example HTML content to be converted into a PDF.
Dim htmlContent As String = "<h1>Hello World!</h1>"
' Asynchronously render the HTML content as a PDF document.
Dim pdf As PdfDocument = Await renderer.RenderHtmlAsPdfAsync(htmlContent)
' Asynchronously save the PDF document to a file.
Await Task.Run(Function() pdf.SaveAs("outputAsync.pdf"))
Console.WriteLine("Working!")
End Function
End Class
在這段程式碼中,我們在 GeneratePdfAsync() 方法中非同步建立了一個 PDF 文件。 ChromePdfRenderer用於創建渲染器,該渲染器在從 HTML 內容創建 PDF 檔案時至關重要。 PdfDocument 類用於從提供的 HTML 字串建立 PDF,然而,您也可以使用它從 HTML 檔案、URL、影像等建立 PDF。 如需瞭解更多關於使用 IronPDF 生成 PDF 的不同方法,請查看 how-to 章節 有關生成 PDF 的內容。
異步處理大型 PDF 檔案
處理大型 PDF 檔案時,使用非同步方法可以顯著提高效能,因為它可以在長時間操作期間釋放主執行緒。 在這個範例中,我選取了一份大型 PDF 文件,並執行 文字萃取 任務,以展示異步 PDF 處理的好處。
using IronPdf;
using System.Threading.Tasks;
using System.IO;
using System;
class Program
{
static async Task Main(string[] args)
{
await LongPdfTask();
}
static async Task LongPdfTask()
{
try
{
// Initialize IronPDF's PdfDocument asynchronously.
PdfDocument pdf = await Task.Run(() => PdfDocument.FromFile("Sample.pdf")).ConfigureAwait(false);
// Extract text from PDF asynchronously with ConfigureAwait to prevent context capture.
string text = await Task.Run(() => pdf.ExtractAllText()).ConfigureAwait(false);
// Write the extracted text to a file asynchronously.
await Task.Run(() => File.WriteAllText("extractedText.txt", text)).ConfigureAwait(false);
Console.WriteLine("Extraction complete!");
}
catch (Exception ex)
{
Console.WriteLine($"Error in LongPdfTask: {ex.Message}");
}
}
}
using IronPdf;
using System.Threading.Tasks;
using System.IO;
using System;
class Program
{
static async Task Main(string[] args)
{
await LongPdfTask();
}
static async Task LongPdfTask()
{
try
{
// Initialize IronPDF's PdfDocument asynchronously.
PdfDocument pdf = await Task.Run(() => PdfDocument.FromFile("Sample.pdf")).ConfigureAwait(false);
// Extract text from PDF asynchronously with ConfigureAwait to prevent context capture.
string text = await Task.Run(() => pdf.ExtractAllText()).ConfigureAwait(false);
// Write the extracted text to a file asynchronously.
await Task.Run(() => File.WriteAllText("extractedText.txt", text)).ConfigureAwait(false);
Console.WriteLine("Extraction complete!");
}
catch (Exception ex)
{
Console.WriteLine($"Error in LongPdfTask: {ex.Message}");
}
}
}
Imports IronPdf
Imports System.Threading.Tasks
Imports System.IO
Imports System
Friend Class Program
Shared Async Function Main(ByVal args() As String) As Task
Await LongPdfTask()
End Function
Private Shared Async Function LongPdfTask() As Task
Try
' Initialize IronPDF's PdfDocument asynchronously.
Dim pdf As PdfDocument = Await Task.Run(Function() PdfDocument.FromFile("Sample.pdf")).ConfigureAwait(False)
' Extract text from PDF asynchronously with ConfigureAwait to prevent context capture.
Dim text As String = Await Task.Run(Function() pdf.ExtractAllText()).ConfigureAwait(False)
' Write the extracted text to a file asynchronously.
Await Task.Run(Sub() File.WriteAllText("extractedText.txt", text)).ConfigureAwait(False)
Console.WriteLine("Extraction complete!")
Catch ex As Exception
Console.WriteLine($"Error in LongPdfTask: {ex.Message}")
End Try
End Function
End Class
在上面的程式碼中,ConfigureAwait(false) 用於執行從大型 PDF 文件中提取所有文字的耗時任務,在我們的例子中,該文件超過 200 頁。
- 匯入與設定:我們程式碼頂端的第一個部分專門用來匯入必要的函式庫和命名空間。 要使用 IronPDF 庫,您需要確保擁有
using IronPdf;。 *類別與主方法:class Program定義了包含此專案主應用程式程式碼的類別。static async Task Main(string[] args)是應用程式的入口點。 在此,我們將其標示為 async,因此我們的異步作業可以在其中執行。 接著,我們使用 await LongPdfTask() 來異步呼叫 LongPdfTask 方法。 -
Try 區塊:我將 LongPdfTask 方法中的程式碼包裝在 try-catch 區塊中,以便優雅地處理任何意外異常。
-
PdfDocument PDF = await Task.Run(() => PdfDocument.FromFile("Sample.pdf")).ConfigureAwait(false): 這一行可以分成三個不同的片段:
- PdfDocument.FromFile("Sample.pdf"):本節同步載入指定的 PDF 檔案到 IronPdf.PdfDocument 物件中。
- await Task.Run(()=>...):在單獨的線程中執行 PDF 載入作業,以避免阻塞主線程。 這使得它成為一項異步作業。
- .ConfigureAwait(false):避免捕捉目前的上下文,這應該可以改善效能並減少死鎖。
-
- string text = await Task.Run(() => pdf.ExtractAllText()).ConfigureAwait(false): 這將執行 IronPDF 文字萃取方法,ExtractAllText() 方法。 同樣地,await Task.Run(() => ...)用來在單獨的線程中異步執行此操作。
- await Task.Run(()=>File.WriteAllText("extractedText.txt",text)).ConfigureAwait(false):藉此,我們再次使用 await Task 方法將擷取的文字以非同步方式寫入 .txt 檔案。
之前

輸出

在 .NET 應用程式中使用 ConfigureAwait 的最佳實作。
何時使用 ConfigureAwait(true) 對 ConfigureAwait(false)?
ConfigureAwait(false)最適合用於在不需要保留同步上下文的庫代碼或背景處理中使用。 通常情況下,這是針對伺服器端程式碼,其效能至關重要。 使用 ConfigureAwait(false)意味著當 await作業完成時,延續不一定會在啟動異步作業的同一個線程上執行。
當涉及 PDF 處理時,實作 ConfigureAwait(false) 有助於在執行多個 PDF 處理任務時發揮最大效能,以避免與上下文切換相關的瓶頸問題。 在處理大量 PDF 檔案時,它也能幫助保持應用程式的順暢運作,只是在控制台應用程式或背景服務中工作時,上下文切換可能是不必要的,這也有助於維持工作效率。
ConfigureAwait(true)最適合用於 UI、任何程式碼的單元測試或 ASP.NET 應用程式,在這些應用程式中,延續必須在相同的上下文上執行,不過如果使用錯誤可能會導致死鎖。 例如,如果您在更新 UI 或存取 httpcontext)。 ConfigureAwait(true) 是預設行為,也可以只寫成 ConfigureAwait。
當與 PDF 處理任務一起使用時,在某些情況下會特別有利,例如您的 PDF 處理程式碼與 UI 緊密整合(當使用 WPF、WinForms 等 UI 應用程式時),例如顯示進度,而您需要擷取同步上下文以確保這些更新發生在 UI 線程上。 在處理線程感應作業時也會有所助益,由於線程親和性的要求,這些作業必須在特定的線程上執行。
在異步 IronPDF 作業中處理異常
在異步程式設計中,處理異常是需要牢記的重要方面,並且需要仔細考慮,未處理的異常可能會終止應用程式。 在異步程式碼周圍使用 try-catch 區塊是優雅地處理任何意外異常的好方法。
舉例來說
public async Task SafeGeneratePdfAsync()
{
try
{
ChromePdfRenderer renderer = new ChromePdfRenderer();
// Asynchronously render HTML as PDF and do not capture the context
PdfDocument pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Error Handling</h1>").ConfigureAwait(false);
// Asynchronously save PDF to file
await Task.Run(() => pdf.SaveAs("output.pdf")).ConfigureAwait(false);
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
}
public async Task SafeGeneratePdfAsync()
{
try
{
ChromePdfRenderer renderer = new ChromePdfRenderer();
// Asynchronously render HTML as PDF and do not capture the context
PdfDocument pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Error Handling</h1>").ConfigureAwait(false);
// Asynchronously save PDF to file
await Task.Run(() => pdf.SaveAs("output.pdf")).ConfigureAwait(false);
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
}
Public Async Function SafeGeneratePdfAsync() As Task
Try
Dim renderer As New ChromePdfRenderer()
' Asynchronously render HTML as PDF and do not capture the context
Dim pdf As PdfDocument = Await renderer.RenderHtmlAsPdfAsync("<h1>Error Handling</h1>").ConfigureAwait(False)
' Asynchronously save PDF to file
Await Task.Run(Function() pdf.SaveAs("output.pdf")).ConfigureAwait(False)
Catch ex As Exception
Console.WriteLine($"An error occurred: {ex.Message}")
End Try
End Function
當使用 ConfigureAwait(false) 繼續任務時,可以使用繼續任務中的 try-catch 處理異常,或者如果使用Task.ContinueWith ,則可以透過Task.Exception屬性處理異常。
如何撰寫代碼的範例可以如下所示:
class Program
{
public static async Task Main(string[] args)
{
await ProcessPdfWithContinuationAsync();
}
static Task ProcessPdfWithContinuationAsync()
{
return Task.Run(() => PdfDocument.FromFile("Sample.pdf"))
.ContinueWith(pdfTask =>
{
if (pdfTask.IsFaulted)
{
// Handle exceptions from loading the PDF
Console.WriteLine($"Error loading PDF: {pdfTask.Exception?.GetBaseException().Message}");
return;
}
var pdf = pdfTask.Result;
// Extract text asynchronously with exception handling
Task.Run(() => pdf.ExtractAllText())
.ContinueWith(extractTask =>
{
if (extractTask.IsFaulted)
{
// Handle exceptions from extracting text
Console.WriteLine($"Error extracting text: {extractTask.Exception?.GetBaseException().Message}");
return;
}
// Proceed if text extraction is successful
Console.WriteLine("Extracted text:");
Console.WriteLine(extractTask.Result);
}, TaskContinuationOptions.OnlyOnRanToCompletion);
}, TaskContinuationOptions.OnlyOnRanToCompletion);
}
}
class Program
{
public static async Task Main(string[] args)
{
await ProcessPdfWithContinuationAsync();
}
static Task ProcessPdfWithContinuationAsync()
{
return Task.Run(() => PdfDocument.FromFile("Sample.pdf"))
.ContinueWith(pdfTask =>
{
if (pdfTask.IsFaulted)
{
// Handle exceptions from loading the PDF
Console.WriteLine($"Error loading PDF: {pdfTask.Exception?.GetBaseException().Message}");
return;
}
var pdf = pdfTask.Result;
// Extract text asynchronously with exception handling
Task.Run(() => pdf.ExtractAllText())
.ContinueWith(extractTask =>
{
if (extractTask.IsFaulted)
{
// Handle exceptions from extracting text
Console.WriteLine($"Error extracting text: {extractTask.Exception?.GetBaseException().Message}");
return;
}
// Proceed if text extraction is successful
Console.WriteLine("Extracted text:");
Console.WriteLine(extractTask.Result);
}, TaskContinuationOptions.OnlyOnRanToCompletion);
}, TaskContinuationOptions.OnlyOnRanToCompletion);
}
}
Friend Class Program
Public Shared Async Function Main(ByVal args() As String) As Task
Await ProcessPdfWithContinuationAsync()
End Function
Private Shared Function ProcessPdfWithContinuationAsync() As Task
Return Task.Run(Function() PdfDocument.FromFile("Sample.pdf")).ContinueWith(Sub(pdfTask)
If pdfTask.IsFaulted Then
' Handle exceptions from loading the PDF
Console.WriteLine($"Error loading PDF: {pdfTask.Exception?.GetBaseException().Message}")
Return
End If
Dim pdf = pdfTask.Result
' Extract text asynchronously with exception handling
Task.Run(Function() pdf.ExtractAllText()).ContinueWith(Sub(extractTask)
If extractTask.IsFaulted Then
' Handle exceptions from extracting text
Console.WriteLine($"Error extracting text: {extractTask.Exception?.GetBaseException().Message}")
Return
End If
' Proceed if text extraction is successful
Console.WriteLine("Extracted text:")
Console.WriteLine(extractTask.Result)
End Sub, TaskContinuationOptions.OnlyOnRanToCompletion)
End Sub, TaskContinuationOptions.OnlyOnRanToCompletion)
End Function
End Class
為什麼選擇 IronPDF 來滿足您的 PDF 處理需求?
IronPDF 的主要功能和優點

IronPDF 是一個功能強大的 C# PDF 函式庫,提供豐富的功能來處理所有 PDF 相關的工作。 IronPDF 完全支援 .NET 8、7、6、.NET Core、Standard 和 Framework,並能在 Windows、Linux、Mac、Docker、Azure 和 AWS 等一系列應用程式環境中執行,無論您偏好何種環境,都能充分發揮 IronPDF 的功能。
使用 IronPDF,您可以從各種檔案和資料類型產生 PDF;包括 HTML 檔案、HTML 字串、URLs、圖片、DOCX和RTF,通常只需要幾行程式碼! 它可以處理 PDF 文件的格式、套用 自訂水印、合併與分割 PDF、處理 PDF加密與 安全性等等。
IronPDF 對異步程式設計的支援
IronPDF 為許多操作提供了異步方法,讓開發人員可以無縫利用 async/await 模式。 這種支援可確保 IronPDF 能夠整合到效能關鍵的應用程式中,而不會犧牲響應能力,使其成為在異步環境中執行 PDF 相關任務的開發人員不可多得的 PDF 工具。
授權
如果您想親自試用 IronPDF 並探索其廣泛的功能,您可以透過 免費試用期輕鬆達成。 IronPDF 安裝快速簡便,您很快就能在 PDF 專案中使用 IronPDF。想要繼續使用並利用其強大的功能來提升您的 PDF 遊戲嗎? 許可證價格僅需 $999 起,並提供慷慨的 30 天退款保證、一整年的產品支援和更新,而且是永久許可證(所以沒有煩人的定期費用!)

範例:使用 ConfigureAwait 和 IronPDF 進行 PDF 生成。
為了以異步方式產生 PDF,我們會使用 IronPDF 來執行渲染 HTML 檔案的程式碼,並儲存結果,同時使用 ConfigureAwait(false) 來確保延續不會不必要地切換回原始同步上下文。
using IronPdf;
using System.Threading.Tasks;
using System;
class Program
{
public static async Task Main(string[] args)
{
await CreateInvoicePdfAsync();
}
static async Task<string> CreateInvoicePdfAsync()
{
// Instance of ChromePdfRenderer to convert HTML to PDF
ChromePdfRenderer renderer = new ChromePdfRenderer();
try
{
// Render HTML file as a PDF asynchronously without capturing the context.
var pdf = await renderer.RenderHtmlFileAsPdfAsync("example.html").ConfigureAwait(false);
// Save the generated PDF asynchronously.
await Task.Run(() => pdf.SaveAs("invoice.pdf")).ConfigureAwait(false);
return "invoice.pdf";
}
catch (Exception ex)
{
Console.WriteLine($"Error generating PDF: {ex.Message}");
return null;
}
}
}
using IronPdf;
using System.Threading.Tasks;
using System;
class Program
{
public static async Task Main(string[] args)
{
await CreateInvoicePdfAsync();
}
static async Task<string> CreateInvoicePdfAsync()
{
// Instance of ChromePdfRenderer to convert HTML to PDF
ChromePdfRenderer renderer = new ChromePdfRenderer();
try
{
// Render HTML file as a PDF asynchronously without capturing the context.
var pdf = await renderer.RenderHtmlFileAsPdfAsync("example.html").ConfigureAwait(false);
// Save the generated PDF asynchronously.
await Task.Run(() => pdf.SaveAs("invoice.pdf")).ConfigureAwait(false);
return "invoice.pdf";
}
catch (Exception ex)
{
Console.WriteLine($"Error generating PDF: {ex.Message}");
return null;
}
}
}
Imports IronPdf
Imports System.Threading.Tasks
Imports System
Friend Class Program
Public Shared Async Function Main(ByVal args() As String) As Task
Await CreateInvoicePdfAsync()
End Function
Private Shared Async Function CreateInvoicePdfAsync() As Task(Of String)
' Instance of ChromePdfRenderer to convert HTML to PDF
Dim renderer As New ChromePdfRenderer()
Try
' Render HTML file as a PDF asynchronously without capturing the context.
Dim pdf = Await renderer.RenderHtmlFileAsPdfAsync("example.html").ConfigureAwait(False)
' Save the generated PDF asynchronously.
Await Task.Run(Function() pdf.SaveAs("invoice.pdf")).ConfigureAwait(False)
Return "invoice.pdf"
Catch ex As Exception
Console.WriteLine($"Error generating PDF: {ex.Message}")
Return Nothing
End Try
End Function
End Class
在這個範例中,我們使用所建立的 async 方法 static async Task
我們也再次實作了 await Task.Run()) => ...)方法,以異步方式執行作業。 最後,我們使用 pdf.SaveAs 方法將新產生的 PDF 檔案儲存為 "invoice.pdf"。 CreateInvoicePdfAsync()方法中的所有程式碼都包裝在 try-catch 區塊中,以處理任何意外的異常。
HTML 檔案

輸出

如您所見,我們成功地將 HTML 檔案異步產生為 PDF,並為我們建立了一個清晰、高品質的 PDF 檔案。
結論
異步程式設計對於建立反應迅速且有效率的 .NET 應用程式而言至關重要,而正確使用 ConfigureAwait 可協助您達到最佳效能,尤其是在撰寫應用程式層級的程式碼時。 在使用 IronPDF 時,利用異步方法以及 ConfigureAwait(false) 可確保您的 PDF 處理任務不會阻塞主線程,從而改善應用程式的整體回應能力。 透過瞭解何時以及如何使用 ConfigureAwait,您可以讓 IronPDF PDF 處理任務更穩健且效能更佳。
現在,您可以在異步程式設計中,將 ConfigureAwait 與 IronPDF 一併使用,成為使用 ConfigureAwait 的專家,您還在等什麼呢? 立即試用 IronPDF,看看它如何改善您的 PDF 相關專案! 如果您想進一步瞭解 IronPDF 作為強大的通用庫代碼所提供的廣泛功能,請務必查看其方便的 使用指南。 或者,如果您想閱讀更多關於在使用 IronPDF 的同時使用異步編程方法的資訊,或者只是想瞭解更多關於 IronPDF 的一般資訊,請查看我們的 部落格文章。 如果您正在尋找更多異步 PDF 產生的範例,請參閱我們的 C# Wait For Seconds 帖文,或我們另一篇關於 C# Task.Run 的文章。



