在生产环境中测试,无水印。
随时随地满足您的需求。
获得30天的全功能产品。
几分钟内就能启动并运行。
在您的产品试用期间,全面访问我们的支持工程团队。
优雅地处理瞬态故障、超时和异常对于构建稳健、弹性应用程序至关重要。 Polly 是一个流行的 .NET 库,提供弹性和瞬态故障处理功能。 在其众多功能中,"重试 "是使用最广泛的策略之一。
在本文中,我们将深入探讨Polly在C#中的重试策略,探索其用法和配置选项,并提供实用的代码示例。 此外,我们将使用IronPDF Library for PDF Generation结合Polly重试功能来生成表单请求结果的PDF。
Polly Retry 是 Polly 库提供的一种策略,使开发人员能够自动重试可能因错误或瞬时故障而失败的操作。 瞬时故障是指由于网络故障、服务不可用或其他瞬时问题而出现的暂时性错误。
利用 Polly 的重试策略,您可以定义重试操作的规则,包括重试的最大次数、多次重试之间的延迟以及重试失败请求的条件。这有助于构建弹性应用程序,使其能够从临时故障中恢复,而不会崩溃或对最终用户造成干扰。
在深入了解代码示例之前,让我们先对如何在 C# 项目中安装和配置 Polly 有一个基本的了解。
您可以通过 NuGet 软件包管理器控制台使用以下命令安装 Polly:
Install-Package Polly
Install-Package Polly
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'Install-Package Polly
或通过 .NET CLI:
dotnet add package Polly
dotnet add package Polly
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'dotnet add package Polly
在您的 C# 文件中,包含 Polly 命名空间:
using Polly;
using Polly;
Imports Polly
让我们从一个简单的示例开始,重试模拟从远程服务获取数据的操作。我们将设置一个重试策略,最多重试 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
在此示例中:
Handle<HttpRequestException>()
指定我们希望处理 HttpRequestException
,并在发生时重试操作。WaitAndRetry()
将重试策略配置为重试 3 次,且每次重试之间有 2 秒的固定延迟(指定最大持续时间)。当发生重试时,onRetry
委托记录一条消息。
指数后退是一种流行的重试策略,请求与重试之间的延迟呈指数增长。 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)
将重试与断路器相结合,可以在服务持续失败时防止重复重试,从而进一步增强弹性。 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)
在此示例中:
CircuitBreaker()
定义了一个电路断路器策略,该策略在出现 3 次异常后中断,并保持打开状态 30 秒。Policy.Wrap()
将电路断路器和重试策略组合成单一策略。
IronPDF C# PDF 库概述 是一个强大的 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");
}
}
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
在使用 IronPDF 时,可能会遇到需要从外部来源获取数据或在生成 PDF 之前执行复杂操作的情况。
在这种情况下,您可能会遇到可能导致 PDF 生成失败的瞬时故障或临时问题。 为了优雅地处理这些瞬时故障,您可以将 Polly Retry 与 IronPdf 结合使用。
在开始之前,请确保在您的项目中安装 IronPDF NuGet 包。
Install-Package IronPdf
让我们来看一个例子,在使用 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)
{
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
这段 C# 代码演示了如何使用 Polly 库与 IronPDF 实现重试策略,生成 PDF 文档。 Main
方法使用 Polly 的 WaitAndRetryAsync
方法初始化一个重试策略。
此策略指定应处理HttpRequestException
,并将操作重试最多3次,初始尝试和重试之间延迟2秒。 如果重试失败,控制台将打印一条信息,说明重试尝试次数和异常信息。
在Main
方法内,重试策略逻辑通过retryPolicy.ExecuteAsync()
异步执行。 在此执行过程中,两个异步操作被串联在一起:FetchDataFromExternalApiAsync()
和 GeneratePdfFromData(data)
。
如果FetchDataFromExternalApiAsync()
失败(因为它被故意设置为通过模拟异常来失败),重试策略将捕获HttpRequestException
,记录重试尝试并重试操作。
FetchDataFromExternalApiAsync()
方法模拟从外部 API 获取数据的过程,包括延迟,并故意抛出 HttpRequestException
以模拟请求失败。
总之,Polly 的重试策略在处理瞬时故障和确保 C# 应用程序的健壮性方面证明是无价之宝。 该工具可灵活配置重试尝试、延迟和条件,使开发人员能够根据具体要求定制弹性策略。
无论是独立使用还是与像IronPDF这样的库结合使用,Polly都能促进创建能从临时故障中优雅恢复的应用程序,从而提升用户体验和软件的可靠性。
通过集成 Polly 的重试功能,开发人员可以构建更具弹性的系统,以适应和恢复瞬时问题,最终提高应用程序的整体质量和可靠性。
IronPDF 是市场上最好的 C# PDF 库,它还提供IronPDF 的试用许可,价格从 $749 美元起。
要了解使用IronPDF进行HTML到PDF转换,请访问以下IronPDF HTML到PDF转换教程。