我正在实现Polly以在C#Web应用程序中重试请求。我的示例代码包含在这篇文章中。该代码可以按预期工作,但是传递给CreateFile()的最后一个参数(当前硬编码为0)需要为retryAttempt的值。如何在Execute Action中获取retryAttempt的值?
return Policy
.Handle<HttpException>(x => x.StatusCode == (HttpStatusCode)429)
.Or<StorageException>()
.WaitAndRetry(maxRetryCount, retryAttempt => TimeSpan.FromMilliseconds(Math.Pow(retryIntervalMs, retryAttempt)))
.Execute(() => CreateFile(fileContent, containerName, fileName, connectionString, 0));
答案 0 :(得分:0)
Polly不提供.Execute(...)
重载,其中重试计数是传递给.Execute(...)
的委托的输入参数之一。这是因为重试仅是许多Polly策略之一,而.Execute(...)
重载的形式对于所有策略类型都必须是通用的。
对于问题中描述的用例,只需:
int count = 0;
return Policy
.Handle<HttpException>(x => x.StatusCode == (HttpStatusCode)429)
.Or<StorageException>()
.WaitAndRetry(maxRetryCount, retryAttempt => TimeSpan.FromMilliseconds(Math.Pow(retryIntervalMs, retryAttempt)))
.Execute(() => CreateFile(fileContent, containerName, fileName, connectionString, count++));
另一种方法是使用Polly的执行范围的Polly.Context
:每次执行都会传播该实例,并且可用于执行的所有部分。
重试策略已经将重试计数传递给onRetry
委托,因此该策略可以将其捕获到执行范围的Context
中:
var retryPolicyCapturingCountIntoContext =
Policy
.Handle<HttpException>(x => x.StatusCode == (HttpStatusCode)429)
.Or<StorageException>()
.WaitAndRetry(
maxRetryCount,
retryAttempt => TimeSpan.FromMilliseconds(Math.Pow(retryIntervalMs, retryAttempt)),
onRetry: (response, delay, retryCount, context) =>
{
context["retrycount"] = retryCount;
});
在通过该策略执行的委托中,我们可以从Context
中选择重试计数(请谨慎处理尚未重试的情况):
retryPolicyCapturingCountIntoContext
.Execute(context =>
{
int retryCount = (context.TryGetValue("retrycount", out var retryObject) && retryObject is int count) ? count : 0;
CreateFile(fileContent, containerName, fileName, connectionString, retryCount);
}, new Context());
如果您希望避免使用context.TryGetValue(...)
防御性代码的干扰,可以选择确保在执行之前始终初始化context["retrycount"]
:
var myContext = new Polly.Context { {"retrycount ", 0} };
retryPolicyCapturingCountIntoContext
.Execute(
context => CreateFile(fileContent, containerName, fileName, connectionString, (int)context["retrycount"]),
myContext);
对于想要捕获每次重试的重试次数(例如进行记录)的用户,请参见Polly retry examples,其中显示了如何将retryCount
作为输入参数传递给onRetry
可以在策略上配置的委托。其他示例here。
对于想要捕获用于成功完成操作的重试总数的用户,可以采用一种通用的方式-例如将遥测作为某些通用执行调度基础结构代码的一部分-参见these examples in Steve Gordon's blog,该使用基于Context
的方法。