跳過到頁腳內容
.NET HELP

Polly Retry (How It Works For Developers)

優雅地處理暫態故障、逾時和異常對建立穩健且有彈性的應用程式至關重要。 Polly 是一個廣受歡迎的 .NET 函式庫,提供彈性和暫態故障處理功能。 在其眾多功能中,"重試"是使用最廣泛的政策之一。

在這篇文章中,我們將深入探討 Polly 的 C# 重試原則,探索其用法和組態選項,並提供實用的程式碼範例。 此外,我們將使用 IronPDF Library for PDF Generation 與 Polly Retry 嘗試產生 PDF 的表單請求結果。

什麼是 Polly Retry?

Polly Retry 是 Polly 函式庫所提供的一項政策,可讓開發人員自動重試可能因錯誤或瞬間故障而失敗的作業。 暫態故障是指由於網路故障、服務無法提供或其他暫態問題而發生的暫時錯誤。

透過 Polly 的重試政策,您可以定義重試作業的規則,包括重試的最大次數、多次重試之間的延遲時間,以及重試失敗請求的條件。這有助於建立有彈性的應用程式,可從暫時的故障中恢復,而不會當機或對終端使用者造成干擾。

開始使用 Polly Retry

在深入了解程式碼範例之前,讓我們先建立一個基本的了解,如何在 C# 專案中安裝和設定 Polly。

安裝 Polly

您可以使用下列指令透過 NuGet 套件管理員控制台安裝 Polly:

Install-Package Polly

或透過 .NET CLI:

dotnet add package Polly

新增 Polly 使用語句

在您的 C# 檔案中,包含 Polly 命名空間:

using Polly;
using Polly;
$vbLabelText   $csharpLabel

基本重試原則範例

讓我們從一個簡單的範例開始,重試模擬從遠端服務取得資料的作業。我們將設定一個重試原則,最多重試 3 次,重試之間的固定超時延遲為 2 秒。

using System;
using System.Net.Http;
using Polly;

namespace PollyRetryExample
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // Define a retry policy that handles HttpRequestException with a maximum of 3 retries
            var retryPolicy = Policy
                .Handle<HttpRequestException>() // Specify the exception type to handle
                .WaitAndRetry(
                    3, // Max retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2), // Fixed retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message);
                    });

            try
            {
                // Execute the action within the context of the retry policy
                retryPolicy.Execute(() =>
                {
                    FetchDataFromRemoteService();
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed after 3 retries: {0}", ex.Message);
            }
        }

        // Simulate fetching data that throws HttpRequestException
        public static void FetchDataFromRemoteService()
        {
            throw new HttpRequestException("Failed to fetch data from remote service");
        }
    }
}
using System;
using System.Net.Http;
using Polly;

namespace PollyRetryExample
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // Define a retry policy that handles HttpRequestException with a maximum of 3 retries
            var retryPolicy = Policy
                .Handle<HttpRequestException>() // Specify the exception type to handle
                .WaitAndRetry(
                    3, // Max retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2), // Fixed retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message);
                    });

            try
            {
                // Execute the action within the context of the retry policy
                retryPolicy.Execute(() =>
                {
                    FetchDataFromRemoteService();
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed after 3 retries: {0}", ex.Message);
            }
        }

        // Simulate fetching data that throws HttpRequestException
        public static void FetchDataFromRemoteService()
        {
            throw new HttpRequestException("Failed to fetch data from remote service");
        }
    }
}
$vbLabelText   $csharpLabel

在這個範例中

  • Handle<HttpRequestException>() 指定我們要處理 HttpRequestException 並在發生時重試操作。
  • WaitAndRetry()設定重試原則,重試 3 次,重試之間有 2 秒的固定延遲(指定的最長時間)。
  • onRetry 代表會在重試發生時記錄一則訊息。

Polly Retry (How It Works For Developers):圖 1

進階重試原則設定

Exponential Backoff

Exponential backoff 是一種流行的重試策略,其中請求與重試之間的延遲會以指數方式增加。 Polly 提供了一個方便的方法,使用 WaitAndRetry() 來實現指數回溯。

var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3, // Max retry attempts
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)), // Exponential delay
        onRetry: (exception, timeSpan, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3, // Max retry attempts
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)), // Exponential delay
        onRetry: (exception, timeSpan, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
$vbLabelText   $csharpLabel

Polly Retry (How It Works For Developers):圖 2

使用斷路器重試

將重試與斷路器結合,可以在服務持續失敗時防止重複重試,進而進一步提升彈性。 Polly 可讓您輕鬆結合重試與斷路策略。

// Define a circuit breaker policy
var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreaker(
        exceptionsAllowedBeforeBreaking: 3, // Number of exceptions before breaking
        durationOfBreak: TimeSpan.FromSeconds(30), // Time circuit stays open
        onBreak: (ex, breakDelay) =>
        {
            Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.");
        },
        onReset: () =>
        {
            Console.WriteLine("Circuit reset.");
        });

// Define a retry policy
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3, // Max retry attempts
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(2), // Fixed retry delay
        onRetry: (exception, timeSpan, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });

// Combine both policies into a single policy wrap
var policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy);
// Define a circuit breaker policy
var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreaker(
        exceptionsAllowedBeforeBreaking: 3, // Number of exceptions before breaking
        durationOfBreak: TimeSpan.FromSeconds(30), // Time circuit stays open
        onBreak: (ex, breakDelay) =>
        {
            Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.");
        },
        onReset: () =>
        {
            Console.WriteLine("Circuit reset.");
        });

// Define a retry policy
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3, // Max retry attempts
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(2), // Fixed retry delay
        onRetry: (exception, timeSpan, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });

// Combine both policies into a single policy wrap
var policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy);
$vbLabelText   $csharpLabel

在這個範例中

  • CircuitBreaker()定義了一個斷路器原則,它會在 3 個異常之後斷開,並維持開啟 30 秒。
  • Policy.Wrap()將斷路器和重試政策合併為單一政策。

Polly Retry (How It Works For Developers):圖 3

IronPDF 簡介

IronPDF C# PDF Library Overview 是一個功能強大的 C# 函式庫,可讓開發人員在其 .NET 應用程式中建立、編輯和處理 PDF 文件。 無論您需要建立發票、報告或任何其他類型的 PDF 文件,IronPDF 都能提供直覺的 API,簡化流程。

使用 IronPDF,您可以輕鬆地將 HTML、CSS 甚至 ASP.NET 網頁轉換為 PDF,使其成為適用於各種應用程式的多功能工具。 此外,它還提供進階功能,例如在 PDF 中加入文字、圖片和互動元素,以及使用加密和數位簽章保護 PDF。

IronPDF 擅長於 HTML 至 PDF 的轉換,確保精確地保留原始版面與樣式。 它非常適合從網頁內容(如報告、發票和文件)產生 PDF。 IronPDF 支援將 HTML 檔案、URL 和原始 HTML 字串轉換為高品質的 PDF 檔案。

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
$vbLabelText   $csharpLabel

使用 IronPdf 重試

在使用 IronPDF 時,可能會遇到需要從外部來源取得資料或在產生 PDF 之前執行複雜操作的情況。

在這種情況下,您可能會遇到可能導致 PDF 生成失敗的暫態故障或臨時問題。 要優雅地處理這些瞬間故障,您可以將 Polly Retry 與 IronPDF 配合使用。

安裝 IronPDF 和 Polly

在開始之前,請務必先在您的專案中安裝 IronPDF NuGet 套件。

Install-Package IronPdf

在 IronPDF 中使用 Polly Retry

讓我們來看看一個範例,在使用 IronPDF 產生 PDF 時,我們使用 Polly Retry 來處理暫態故障。 在以下範例中,我們將模擬從外部 API 取得資料,然後根據這些資料產生 PDF。 我們會使用 Polly Retry 來執行資料擷取作業,以防失敗。

using System;
using System.Net.Http;
using System.Threading.Tasks;
using IronPdf;
using Polly;

namespace IronPdfWithPollyRetry
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            // Define a retry policy with async capability
            var retryPolicy = Policy
                .Handle<HttpRequestException>() // Specify exception type to handle
                .WaitAndRetryAsync(
                    3, // Retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2), // Calculated retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry " + retryCount + " due to " + exception.Message);
                    });

            // Execute the retry policy asynchronously
            var pdf = await retryPolicy.ExecuteAsync(async () =>
            {
                var data = await FetchDataFromExternalApiAsync(); // Fetch data from an external source
                return GeneratePdfFromData(data); // Generate PDF using fetched data
            });

            pdf.SaveAs("GeneratedDocument.pdf");
        }

        // Simulate fetching data from an external API
        static async Task<string> FetchDataFromExternalApiAsync()
        {
            await Task.Delay(100); // Simulate delay
            throw new HttpRequestException("Failed to fetch data from external API");
        }

        // Generate PDF using IronPDF based on the fetched data
        static PdfDocument GeneratePdfFromData(string data)
        {
            var htmlContent = "<html><body><h1>Data: " + data + "</h1></body></html>";
            var renderer = new ChromePdfRenderer();
            return renderer.RenderHtmlAsPdf(htmlContent);
        }
    }
}
using System;
using System.Net.Http;
using System.Threading.Tasks;
using IronPdf;
using Polly;

namespace IronPdfWithPollyRetry
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            // Define a retry policy with async capability
            var retryPolicy = Policy
                .Handle<HttpRequestException>() // Specify exception type to handle
                .WaitAndRetryAsync(
                    3, // Retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2), // Calculated retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry " + retryCount + " due to " + exception.Message);
                    });

            // Execute the retry policy asynchronously
            var pdf = await retryPolicy.ExecuteAsync(async () =>
            {
                var data = await FetchDataFromExternalApiAsync(); // Fetch data from an external source
                return GeneratePdfFromData(data); // Generate PDF using fetched data
            });

            pdf.SaveAs("GeneratedDocument.pdf");
        }

        // Simulate fetching data from an external API
        static async Task<string> FetchDataFromExternalApiAsync()
        {
            await Task.Delay(100); // Simulate delay
            throw new HttpRequestException("Failed to fetch data from external API");
        }

        // Generate PDF using IronPDF based on the fetched data
        static PdfDocument GeneratePdfFromData(string data)
        {
            var htmlContent = "<html><body><h1>Data: " + data + "</h1></body></html>";
            var renderer = new ChromePdfRenderer();
            return renderer.RenderHtmlAsPdf(htmlContent);
        }
    }
}
$vbLabelText   $csharpLabel

此 C# 程式碼示範如何使用 Polly 函式庫與 IronPDF 實作重試政策,以產生 PDF 文件。 Main 方法使用 Polly 的 WaitAndRetryAsync 方法初始化重試原則。

此政策指定應處理 HttpRequestException 並重試操作最多 3 次,且初次嘗試與重試之間的延遲時間為 2 秒。 如果重試失敗,則會將訊息列印到控制台,指出重試嘗試的次數和異常訊息。

Main 方法中,重試原則邏輯會使用 retryPolicy.ExecuteAsync() 以異步方式執行。 在此執行中,兩個異步操作被串連在一起:FetchDataFromExternalApiAsync()GeneratePdfFromData(data).

如果FetchDataFromExternalApiAsync()失敗(就像它故意設定的模擬異常一樣),重試原則會捕捉HttpRequestException,記錄重試嘗試,並重試操作。

FetchDataFromExternalApiAsync() 方法模擬在延遲的情況下從外部 API 取得資料,並故意拋出 HttpRequestException 以模擬失敗的請求。

Polly Retry (How It Works For Developers):圖 4

結論

總而言之,Polly 的重試原則對於處理 C# 應用程式中的暫態故障並確保穩健性而言,證明是無價之寶。 其在設定重試嘗試、延遲和條件方面的靈活性,可讓開發人員根據特定需求量身打造彈性策略。

無論是獨立使用或與 IronPDF 等函式庫搭配使用,Polly 都能協助建立可從暫時故障中優雅恢復的應用程式,提升使用者體驗與軟體的可靠性。

透過整合 Polly 的重試功能,開發人員可以建立更具彈性的系統,能夠適應並從瞬間問題中恢復,最終提升應用程式的整體品質與可靠性。

IronPDF 是市面上最好的 C# PDF 函式庫,它也提供 IronPDF的試用授權,價格從 $799 USD 起。

要瞭解如何使用 IronPDF 將 HTML 轉換為 PDF,請造訪以下 IronPDF HTML 至 PDF 轉換教學

常見問題解答

什麼是 C# 中的 Polly Retry?

Polly Retry 是 C# 中 Polly 函式庫的一項功能,可讓開發人員自動重試因網路故障或服務不可用等臨時問題而失敗的作業。這有助於建立彈性的應用程式,從容處理短暫故障。

如何使用 Polly 實作基本的重試政策?

您可以在 Polly 中實作基本的重試原則,方法是處理如 HttpRequestException 之類的異常,並將其設定為最多重試三次,每次嘗試之間有兩秒的固定延遲。

在 Polly 中,指數回報(exponential backoff)有什麼意義?

Polly 中的 Exponential backoff 用於以指數方式增加重試之間的延遲,有助於降低故障期間服務的負載。這可以使用 Polly 的 WaitAndRetry 方法來實作,該方法會根據指數成長來計算延遲。

如何為 C# 專案安裝 Polly?

您可以使用 NuGet Package Manager Console 使用 Install-Package Polly 指令,或透過 .NET CLI 使用 dotnet add package Polly 指令,在 C# 專案中安裝 Polly。

Polly 的重試政策可以與其他彈性策略結合嗎?

是的,Polly 允許您使用 Policy.Wrap 方法將其重試原則與其他彈性策略 (例如斷路器) 結合,以加強應用程式的彈性,並在服務持續失敗時防止重複重試。

如何在 C# 中將 HTML 轉換為 PDF?

您可以使用 IronPDF 的 RenderHtmlAsPdf 等方法將 HTML 字串轉換為 PDF。IronPDF 還支援將 HTML 檔案和網頁(包括 CSS)轉換成 PDF 格式。

為什麼 Polly 的重試政策對 C# 應用程式很重要?

Polly 的重試原則對於處理 C# 應用程式中的暫態故障、確保穩健性,以及透過允許系統在不當機的情況下從暫時故障中恢復來改善使用者體驗,是至關重要的。

如何在 PDF 生成流程中實施重試策略?

在產生 PDF 時,可使用 Polly 實作重試策略,以處理暫態故障。透過將 Polly 的重試功能與 IronPDF 整合,您可以在暫時發生網路或服務問題時多次嘗試 PDF 作業。

如何安裝 IronPDF 之類的 C# PDF 函式庫?

IronPDF 可透過 NuGet 套件管理員使用 Install-Package IronPdf 指令安裝,讓您可以在 C# 應用程式中建立、編輯和處理 PDF 文件。

使用 IronPDF 生成 PDF 有哪些優點?

IronPDF 提供了在 .NET 應用程式中建立和操作 PDF 文件的強大功能。它支援將 HTML、CSS 和網頁轉換為 PDF、新增文字和圖片,以及使用加密來保護文件。

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

Jacob Mellor 是 Iron Software 的首席技術長,也是開創 C# PDF 技術的有遠見的工程師。作為 Iron Software 核心程式碼庫背後的原始開發人員,他從公司成立之初就塑造了公司的產品架構,與首席執行官 Cameron Rimington 一起將公司轉型為一家 50 多人的公司,為 NASA、Tesla 和全球政府機構提供服務。

Jacob 持有曼徹斯特大學土木工程一級榮譽工程學士學位 (BEng)(1998-2001 年)。

Jacob 於 1999 年在倫敦開設了他的第一家軟體公司,並於 2005 年創建了他的第一個 .NET 元件,之後,他專門解決微軟生態系統中的複雜問題。

他的旗艦產品 IronPDF & Iron Suite for .NET 函式庫在全球的 NuGet 安裝量已超過 3000 萬次,他的基礎程式碼持續為全球使用的開發人員工具提供動力。Jacob 擁有 25 年的商業經驗和 41 年的編碼專業知識,他一直專注於推動企業級 C#、Java 和 Python PDF 技術的創新,同時指導下一代的技術領導者。