.NET 幫助

Polly 重試(開發人員如何運作)

在構建穩健且具備彈性的應用程式時,妥善處理短暫性故障、超時和例外情況至關重要。 Polly 是一個受歡迎的 .NET 庫,提供彈性及暫時性故障處理功能。 在眾多功能中,「重試」是其中使用最廣泛的政策之一。

在本文中,我們將深入探討Polly 在 C# 中的重試政策,探索其使用及配置選項,並提供實用的程式碼範例。 此外,我們將使用IronPDF Library for PDF Generation,並嘗試使用Polly Retry來生成表單請求結果的PDF。

什麼是 Polly 重試?

Polly Retry 是由 Polly 庫提供的一種策略,使開發人員能夠自動重試可能因錯誤或瞬時故障而失敗的操作。 瞬態故障是由於網路故障、服務不可用或其他暫時性問題而產生的臨時錯誤。

透過Polly的重試策略,您可以定義重試操作的規則,包括最大重試次數、多次重試之間的延遲時間,以及重試失敗請求的條件。這有助於構建能夠從臨時故障中恢復的穩健應用程序,而不會崩潰或對終端使用者造成中斷。

Polly Retry 入門指南

在探討程式碼範例之前,我們先來建立對在 C# 專案中安裝和配置 Polly 的基本了解。

安裝Polly

您可以使用以下命令通過 NuGet 套件管理器控制台安裝 Polly:

Install-Package Polly
Install-Package Polly
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'Install-Package Polly
$vbLabelText   $csharpLabel

或者通過 .NET CLI:

dotnet add package Polly
dotnet add package Polly
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'dotnet add package Polly
$vbLabelText   $csharpLabel

使用添加 Polly 語句

在您的 C# 文件中,包含 Polly 命名空間:

using Polly;
using Polly;
Imports Polly
$vbLabelText   $csharpLabel

基本重試策略範例

讓我們從一個簡單的例子開始,我們重試一個模擬從遠程服務獲取數據的操作。我們將設置一個重試策略,最多重試3次,並在每次重試之間設置固定的2秒超時延遲。

using System;
using System.Net.Http;
using Polly;
namespace PollyRetryExample
{
    public class Program
    {
        public static void Main(string[] args)
        {
           var retryPolicy = Policy
                .Handle<HttpRequestException>()
                .WaitAndRetry(
                    3,
                    retryAttempt => TimeSpan.FromSeconds(2),
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message);
                    });
            try
            {
                retryPolicy.Execute(() =>
                {
                    FetchDataFromRemoteService();
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed after 3 retries: {0}", ex.Message);
            }
        }
        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)
        {
           var retryPolicy = Policy
                .Handle<HttpRequestException>()
                .WaitAndRetry(
                    3,
                    retryAttempt => TimeSpan.FromSeconds(2),
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message);
                    });
            try
            {
                retryPolicy.Execute(() =>
                {
                    FetchDataFromRemoteService();
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed after 3 retries: {0}", ex.Message);
            }
        }
        public static void FetchDataFromRemoteService()
        {
            throw new HttpRequestException("Failed to fetch data from remote service");
        }
    }
}
Imports System
Imports System.Net.Http
Imports Polly
Namespace PollyRetryExample
	Public Class Program
		Public Shared Sub Main(ByVal args() As String)
		   Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetry(3, Function(retryAttempt) TimeSpan.FromSeconds(2), Sub(exception, timeSpan, retryCount, context)
			   Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message)
		   End Sub)
			Try
				retryPolicy.Execute(Sub()
					FetchDataFromRemoteService()
				End Sub)
			Catch ex As Exception
				Console.WriteLine("Failed after 3 retries: {0}", ex.Message)
			End Try
		End Sub
		Public Shared Sub FetchDataFromRemoteService()
			Throw New HttpRequestException("Failed to fetch data from remote service")
		End Sub
	End Class
End Namespace
$vbLabelText   $csharpLabel

在此範例中:

  • Handle<HttpRequestException>() 指定我們希望處理 HttpRequestException,並在發生時重試操作。
  • WaitAndRetry() 將重試策略配置為重試 3 次,並且每次重試之間有固定的 2 秒延遲(指定的最大持續時間)。
  • onRetry 委派在重試發生時記錄一條消息。

    Polly Retry (開發人員如何使用):圖 1

高級重試策略配置

指数退避

指數退避是一種流行的重試策略,其特點是請求與重試之間的延遲指數性增加。 Polly 提供了一種便利的方法來使用WaitAndRetry()實現指數退避。

var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3,
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)),
        onRetry: (exception, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3,
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)),
        onRetry: (exception, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetry(retryCount:= 3, sleepDurationProvider:= Function(attempt) TimeSpan.FromSeconds(Math.Pow(2, attempt)), onRetry:= Sub(exception, retryCount, context)
	Console.WriteLine($"Retry {retryCount} due to {exception.Message}")
End Sub)
$vbLabelText   $csharpLabel

Polly Retry(它如何為開發人員工作):圖2

使用熔斷器重試

將重試與斷路器結合起來,可以進一步增強韌性,防止在服務持續失敗時重複重試。 Polly可以輕鬆結合重試和熔斷器策略。

var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreaker(
        exceptionsAllowedBeforeBreaking: 3,
        durationOfBreak: TimeSpan.FromSeconds(30),
        onBreak: (ex, breakDelay) =>
        {
            Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.");
        },
        onReset: () =>
        {
            Console.WriteLine("Circuit reset.");
        });
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3,
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(2),
        onRetry: (exception, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
var policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy);
var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreaker(
        exceptionsAllowedBeforeBreaking: 3,
        durationOfBreak: TimeSpan.FromSeconds(30),
        onBreak: (ex, breakDelay) =>
        {
            Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.");
        },
        onReset: () =>
        {
            Console.WriteLine("Circuit reset.");
        });
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3,
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(2),
        onRetry: (exception, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
var policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy);
Dim circuitBreakerPolicy = Policy.Handle(Of HttpRequestException)().CircuitBreaker(exceptionsAllowedBeforeBreaking:= 3, durationOfBreak:= TimeSpan.FromSeconds(30), onBreak:= Sub(ex, breakDelay)
			Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.")
End Sub, onReset:= Sub()
			Console.WriteLine("Circuit reset.")
End Sub)
Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetry(retryCount:= 3, sleepDurationProvider:= Function(attempt) TimeSpan.FromSeconds(2), onRetry:= Sub(exception, retryCount, context)
	Console.WriteLine($"Retry {retryCount} due to {exception.Message}")
End Sub)
Dim policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy)
$vbLabelText   $csharpLabel

在此範例中:

  • CircuitBreaker() 定義了一個斷路器策略,該策略在發生3次異常後中斷,並保持開路狀態30秒。
  • Policy.Wrap() 將斷路器和重試策略結合為單一策略。

    Polly Retry(適用於開發者的運作方式):圖 3

IronPDF 介紹

IronPDF C# PDF Library 概述 是一個強大的 C# 函式庫,它允許開發人員在其 .NET 應用程式中創建、編輯和操作 PDF 文件。 無論您需要創建發票、報告或任何其他類型的 PDF 文件,IronPDF 提供了一個直觀的 API,簡化了這個過程。

使用 IronPDF,您可以輕鬆將 HTML、CSS,甚至 ASP.NET 網頁轉換為 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");
    }
}
Imports IronPdf

Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim renderer = New ChromePdfRenderer()

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

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

		' 3. Convert URL to PDF
		Dim url = "http://ironpdf.com" ' Specify the URL
		Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
		pdfFromUrl.SaveAs("URLToPDF.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

Polly Retry 與 IronPDF

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

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

安裝 IronPDF 和 Polly

在開始之前,請確保在您的專案中安裝 IronPDF NuGet 套件。

Install-Package IronPdf

在 IronPDF 中使用 Polly Retry

讓我們來看一個例子,使用 Polly Retry 在使用 IronPDF 生成 PDF 時處理短暫性故障。 在以下示例中,我們將模擬從外部 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)
        {
            var retryPolicy = Policy
                .Handle<HttpRequestException>()
                .WaitAndRetryAsync(
                    3,//retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2),//calculated retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry " + retryCount + " due to " + exception.Message);
                    });
            var pdf = await retryPolicy.ExecuteAsync(async () =>
            {
                var data = await FetchDataFromExternalApiAsync();
                return GeneratePdfFromData(data);
            });
            pdf.SaveAs("GeneratedDocument.pdf");
        }
        static async Task<string> FetchDataFromExternalApiAsync()
        {
            // Simulate fetching data from an external API
            await Task.Delay(100); // Simulate delay
            throw new HttpRequestException("Failed to fetch data from external API");
        }
        static PdfDocument GeneratePdfFromData(string data)
        {
            // Generate PDF using IronPDF based on the fetched 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)
        {
            var retryPolicy = Policy
                .Handle<HttpRequestException>()
                .WaitAndRetryAsync(
                    3,//retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2),//calculated retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry " + retryCount + " due to " + exception.Message);
                    });
            var pdf = await retryPolicy.ExecuteAsync(async () =>
            {
                var data = await FetchDataFromExternalApiAsync();
                return GeneratePdfFromData(data);
            });
            pdf.SaveAs("GeneratedDocument.pdf");
        }
        static async Task<string> FetchDataFromExternalApiAsync()
        {
            // Simulate fetching data from an external API
            await Task.Delay(100); // Simulate delay
            throw new HttpRequestException("Failed to fetch data from external API");
        }
        static PdfDocument GeneratePdfFromData(string data)
        {
            // Generate PDF using IronPDF based on the fetched data
            var htmlContent = "<html><body><h1>Data: " + data + "</h1></body></html>";
            var renderer = new ChromePdfRenderer();
            return renderer.RenderHtmlAsPdf(htmlContent);
        }
    }
}
Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports IronPdf
Imports Polly
Namespace IronPdfWithPollyRetry
	Public Class Program
		Public Shared Async Function Main(ByVal args() As String) As Task
			Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetryAsync(3, Function(retryAttempt) TimeSpan.FromSeconds(2), Sub(exception, timeSpan, retryCount, context)
				Console.WriteLine("Retry " & retryCount & " due to " & exception.Message)
			End Sub)
			Dim pdf = Await retryPolicy.ExecuteAsync(Async Function()
				Dim data = Await FetchDataFromExternalApiAsync()
				Return GeneratePdfFromData(data)
			End Function)
			pdf.SaveAs("GeneratedDocument.pdf")
		End Function
		Private Shared Async Function FetchDataFromExternalApiAsync() As Task(Of String)
			' Simulate fetching data from an external API
			Await Task.Delay(100) ' Simulate delay
			Throw New HttpRequestException("Failed to fetch data from external API")
		End Function
		Private Shared Function GeneratePdfFromData(ByVal data As String) As PdfDocument
			' Generate PDF using IronPDF based on the fetched data
			Dim htmlContent = "<html><body><h1>Data: " & data & "</h1></body></html>"
			Dim renderer = New ChromePdfRenderer()
			Return renderer.RenderHtmlAsPdf(htmlContent)
		End Function
	End Class
End Namespace
$vbLabelText   $csharpLabel

此 C# 代码演示了如何使用 Polly 库在 IronPDF 中实现重试策略以生成 PDF 文档。 Main 方法使用 Polly 的 WaitAndRetryAsync 方法初始化重試策略。

此政策規定應該處理HttpRequestException,並在初始嘗試和重試之間每次延遲2秒的情況下重新嘗試操作最多3次。 如果重試失敗,會在控制台上打印一條消息,顯示重試嘗試的次數和例外的訊息。

Main方法中,重試策略邏輯使用retryPolicy.ExecuteAsync()異步執行。 在這個執行過程中,兩個非同步操作被鏈接在一起:FetchDataFromExternalApiAsync()GeneratePdfFromData(data)

如果 FetchDataFromExternalApiAsync() 失敗(由於它已被故意設置為使用模擬例外情況),重試策略將捕捉到 HttpRequestException,記錄重試嘗試,並再次嘗試執行該操作。

FetchDataFromExternalApiAsync() 方法模擬從外部 API 獲取數據,附帶延遲並故意拋出 HttpRequestException 以模擬失敗的請求。

Polly Retry (開發人員的運作方式):圖4

結論

總之,Polly 的重試策略在處理瞬時故障和確保 C# 應用程式的穩健性方面顯得非常重要。 其在配置重试次數、延遲和條件方面的靈活性,使開發人員能夠根據特定要求定制彈性策略。

無論是獨立使用還是與像IronPDF這樣的庫結合使用,Polly 都能協助創建能夠從暫時失敗中優雅恢復的應用程式,提高用戶體驗和軟體的可靠性。

通過整合Polly的重試功能,開發者可以構建出更加穩健的系統,能夠適應和從短暫問題中恢復,從而最終提高應用程式的整體質量和可靠性。

IronPDF 是市場上最好的 C# PDF 庫,它還提供 IronPDF 的試用許可證,價格從 $749 美元起。

如需了解使用 IronPDF 進行 HTML 到 PDF 的轉換,請訪問以下IronPDF HTML 到 PDF 轉換教程

Chipego
奇佩戈·卡林达
軟體工程師
Chipego 擁有天生的傾聽技能,這幫助他理解客戶問題,並提供智能解決方案。他在獲得信息技術理學學士學位後,于 2023 年加入 Iron Software 團隊。IronPDF 和 IronOCR 是 Chipego 專注的兩個產品,但隨著他每天找到新的方法來支持客戶,他對所有產品的了解也在不斷增長。他喜歡在 Iron Software 的協作生活,公司內的團隊成員從各自不同的經歷中共同努力,創造出有效的創新解決方案。當 Chipego 離開辦公桌時,他常常享受讀好書或踢足球的樂趣。
< 上一頁
C# iList(開發人員如何使用)
下一個 >
WebClient C#(它對開發人員的工作原理)