在实际环境中测试
在生产中测试无水印。
随时随地为您服务。
优雅地处理瞬态故障、超时和异常对于构建稳健、弹性应用程序至关重要。 Polly 是一个流行的 .NET 库,提供弹性和瞬态故障处理功能。 在其众多功能中,"重试 "是使用最广泛的策略之一。
在本文中,我们将深入探讨C# 中的波莉重试策略此外,译文还将探讨其用法和配置选项,并提供实用的代码示例。 此外,我们还将使用用于生成 PDF 的 IronPDF 库Polly Retry 尝试生成 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
在此示例中:
HttpRequestException
并在发生时重试操作。当发生重试时,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)
在此示例中:
`Policy.Wrap()将断路器和重试策略合并为一个策略。
IronPDF C# PDF 库概述PDF.NET 是一个功能强大的 C# 库,允许开发人员在其 .NET 应用程序中创建、编辑和处理 PDF 文档。 无论您是需要创建发票、报告还是其他任何类型的 PDF 文档,IronPDF 都能提供直观的 API,简化流程。
使用 IronPDF,您可以轻松地将 HTML、CSS 甚至 ASP.NET 网页转换为 PDF,使其成为适用于各种应用的多功能工具。 此外,它还提供了一些高级功能,如在 PDF 中添加文本、图像和交互式元素,以及使用加密和数字签名保护 PDF。
在使用 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(数据)`.
如果 FetchDataFromExternalApiAsync()
失败(因为它有意设置了一个模拟例外)在.NET 中,重试策略将捕获 "HttpRequestException",记录重试尝试并重试操作。
FetchDataFromExternalApiAsync()该方法模拟从外部 API 获取数据的延迟,并故意抛出 "HttpRequestException "以模拟请求失败。
总之,Polly 的重试策略在处理瞬时故障和确保 C# 应用程序的健壮性方面证明是无价之宝。 该工具可灵活配置重试尝试、延迟和条件,使开发人员能够根据具体要求定制弹性策略。
无论是独立使用还是与下列库结合使用IronPDFPolly 可帮助创建从临时故障中优雅恢复的应用程序,从而增强用户体验和软件的可靠性。
通过集成 Polly 的重试功能,开发人员可以构建更具弹性的系统,以适应和恢复瞬时问题,最终提高应用程序的整体质量和可靠性。
IronPDF 是市场上最好的 C# PDF 库,它还提供了一个IronPDF 试用许可证价格从 $749 美元起。
要了解使用 IronPDF 将 HTML 转换为 PDF,请访问以下内容IronPDF HTML 至 PDF 转换教程.