跳至頁尾內容
.NET 幫助

C# ConfigureAwait(開發者如何理解它的工作原理)

身為開發人員,異步程式設計是非常有益的,它可以改善您應用程式的效能、效率和反應能力,尤其是那些需要花費大量時間才能完成的作業。 透過使用 ConfigureAwait(false) 可以避免某些情況下的死鎖。 死鎖發生在異步程式設計中,當同步上下文(例如桌面應用程式中的 UI 線程)期望操作完成後才繼續進行。 不過,等待的任務仍在等待同步上下文可用,形成循環等待。

今天,我們將探討 ConfigureAwait 如何與 IronPDF 搭配使用,透過異步程式設計有效率地執行 PDF 處理任務。 IronPDF 是一個 .NET PDF 函式庫,讓處理 PDF 相關工作變得輕而易舉。 憑藉強大的功能、強大的跨平台相容性以及廣泛的說明文件,它是您開發人員工具包中不可或缺的強大 PDF 工具。

瞭解 C# 中的異步程式設計;

什麼是異步程式設計?

異步程式設計指的是一種編寫程式碼的方法,允許某些作業獨立於主應用程式線程執行。 這對需要等待的長時間執行任務非常有用,例如 I/O 作業。 透過允許這些任務在不阻塞主線程的情況下執行,應用程式可以在這些任務需要時間完成時繼續執行,最終改善應用程式的效能與反應能力。

異步程式碼中 ConfigureAwait 的作用

ConfigureAwait是異步程式設計中的一種方法,用來控制延續的執行方式。 Continuation 是在 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:

C# ConfigureAwait (How It Works For Developers):圖 1

或者,在套件管理員控制台執行以下指令:

Install-Package IronPdf

要開始在程式碼中使用 IronPDF,請確保您已將 using IronPdf; 語句置於程式碼檔案的頂端。如需在您的環境中設定 IronPdf 的更深入指南,請參閱其 getting started 頁面。

使用 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!");
    }
}
$vbLabelText   $csharpLabel

在此程式碼中,我們在 GeneratePdfAsync() 方法中以異步方式建立 PDF 文件。 ChromePdfRenderer用於創建渲染器,該渲染器在從 HTML 內容創建 PDF 檔案時至關重要。 PdfDocument 類用於從提供的 HTML 字串建立 PDF,然而,您也可以使用它從 HTML 檔案URL影像等建立 PDF。 如需瞭解更多關於使用 IronPDF 生成 PDF 的不同方法,請查看 how-to 章節 有關生成 PDF 的內容。

異步處理大型 PDF 檔案

在處理大型 PDF 檔案時,使用 ConfigureAwait(false) 的異步方法可以在長時間的作業中釋放主線程來大幅提升效能。 在這個範例中,我選取了一份大型 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}");
        }
    }
}
$vbLabelText   $csharpLabel

在上述程式碼中,ConfigureAwait(false) 是在從大型 PDF 檔案中萃取所有文字這項耗時的大型任務中使用,在我們的案例中,PDF 檔案長達 200 多頁。

  • 匯入與設定:我們程式碼頂端的第一個部分專門用來匯入必要的函式庫和命名空間。 您需要確保有 using IronPdf; 來使用 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 檔案。

之前

C# ConfigureAwait (How It Works For Developers):圖 2

輸出

C# ConfigureAwait (How It Works For Developers):圖 3

在 .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}");
    }
}
$vbLabelText   $csharpLabel

當使用 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);
    }
}
$vbLabelText   $csharpLabel

為什麼選擇 IronPDF 來滿足您的 PDF 處理需求?

IronPDF 的主要功能和優點

C# ConfigureAwait (How It Works For Developers):圖 4

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圖片DOCXRTF,通常只需要幾行程式碼! 它可以處理 PDF 文件的格式、套用 自訂水印合併與分割 PDF、處理 PDF加密安全性等等。

IronPDF 對異步程式設計的支援

IronPdf 為許多操作提供了異步方法,讓開發人員可以無縫利用 async/await 模式。 這種支援可確保 IronPDF 能夠整合到效能關鍵的應用程式中,而不會犧牲響應能力,使其成為在異步環境中執行 PDF 相關任務的開發人員不可多得的 PDF 工具。

授權

如果您想親自試用 IronPdf 並探索其廣泛的功能,您可以透過 免費試用期輕鬆達成。 IronPDF 安裝快速簡便,您很快就能在 PDF 專案中使用 IronPDF。想要繼續使用並利用其強大的功能來提升您的 PDF 遊戲嗎? 授權僅需$799起,並提供慷慨的 30 天退款保證、一整年的產品支援與更新,以及永久授權 (因此沒有討厭的經常性費用!)

C# ConfigureAwait (How It Works For Developers):圖 5

範例:使用 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;
        }
    }
}
$vbLabelText   $csharpLabel

在這個範例中,我們使用所建立的 async 方法 static async TaskCreateInvoicePdfAsync()來從 RenderHtmlFileAsPdfAsync 方法。 我們使用 ConfigureAwait(false)來防止在原始同步上下文中繼續執行此任務,以改善非使用者介面應用程式的效能。

我們也再次實作了 await Task.Run()) => ...)方法,以異步方式執行作業。 最後,我們使用 pdf.SaveAs 方法將新產生的 PDF 檔案儲存為 "invoice.pdf"。 CreateInvoicePdfAsync()方法中的所有程式碼都包裝在 try-catch 區塊中,以處理任何意外的異常。

HTML 檔案

C# ConfigureAwait (How It Works For Developers):圖 6

輸出

C# ConfigureAwait (How It Works For Developers):圖 7

如您所見,我們成功地將 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 的文章。

常見問題解答

非同步程式設計中的 ConfigureAwait 是什麼?

ConfigureAwait 是非同步程式設計中用於指定 await 表達式之後的延續程式碼應該在原始同步上下文中執行,還是在不同的同步上下文中執行的方法。使用ConfigureAwait(false)可以避免捕獲同步上下文,從而有助於防止死鎖。

如何在C#中異步生成PDF?

您可以使用 IronPDF 的非同步方法在 C# 中非同步產生 PDF 檔案。這可以提高效率和回應速度,尤其是在處理大型檔案時,因為它不會阻塞主應用程式執行緒。

為什麼我應該在 C# 應用程式中使用 ConfigureAwait(false)?

在 C# 應用程式中使用ConfigureAwait(false)可以提高效能,它允許延續在執行緒池執行緒上運行,避免不必要的上下文切換和潛在的死鎖,尤其是在函式庫程式碼中。

在 .NET 使用 IronPDF 進行 PDF 處理有哪些好處?

IronPDF 提供豐富的功能,例如 PDF 生成、文字擷取和合併,並具有出色的跨平台相容性。它支援非同步編程,因此非常適合對性能要求極高的應用。

如何處理非同步PDF處理任務中的異常?

非同步 PDF 處理任務中的異常可以透過在非同步方法周圍使用 try-catch 區塊進行管理。 IronPDF 讓您可以優雅地處理異常,從而確保應用程式的穩定性。

IronPDF 如何利用非同步方法改進 PDF 處理?

IronPDF 中的非同步方法可讓您在不阻塞主應用程式執行緒的情況下執行 PDF 處理任務。這可以提高應用程式的反應速度和效率,尤其是在處理大型或複雜的 PDF 操作時。

在函式庫程式碼中使用 ConfigureAwait 時需要考慮哪些關鍵因素?

在程式庫程式碼中使用 ConfigureAwait 時,請務必使用ConfigureAwait(false)來避免擷取同步上下文,從而提高效能並防止在非同步操作中出現死鎖。

如何在 C# 專案中設定 IronPDF?

若要在 C# 專案中設定 IronPDF,可以使用 NuGet 套件管理器搜尋 IronPDF,或在套件管理器控制台中執行指令Install-Package IronPdf

IronPDF為何對開發人員來說是一款有價值的工具?

IronPDF 功能強大,包括 PDF 生成、文字擷取和加密等,因此對開發者來說是一款非常有價值的工具。它支援非同步處理,有助於開發者創建響應迅速且高效的應用程式。

Jacob Mellor,Team Iron 首席技術官
首席技術長

Jacob Mellor 是 Iron Software 的首席技術官,也是一位富有遠見的工程師,率先開發了 C# PDF 技術。作為 Iron Software 核心程式碼庫的最初開發者,他自公司成立之初便參與塑造了其產品架構,並與執行長 Cameron Rimington 一起將其發展成為一家擁有 50 多名員工、服務於 NASA、特斯拉和全球政府機構的公司。

Jacob 於 1998 年至 2001 年在曼徹斯特大學獲得土木工程一級榮譽學士學位。 1999 年,他在倫敦創辦了自己的第一家軟體公司;2005 年,他創建了自己的第一個 .NET 元件。此後,他專注於解決微軟生態系統中的複雜問題。

他的旗艦產品 IronPDF 和 IronSuite .NET 庫在全球 NuGet 上的安裝量已超過 3000 萬次,其基礎程式碼持續為全球開發者工具提供支援。憑藉 25 年的商業經驗和 41 年的程式設計專長,Jacob 始終致力於推動企業級 C#、Java 和 Python PDF 技術的創新,同時指導下一代技術領導者。