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 的 execution-scoped Polly.Context
: this 的一个实例随每次执行传播,并且可用于执行的所有部分。
重试策略已经将重试计数传递给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 重试示例,展示如何retryCount
将输入参数作为输入参数传递给onRetry
可以在策略上配置的委托。进一步的例子在这里。
对于希望以通用方式捕获用于成功操作的重试总数的用户(例如将遥测作为某些通用执行调度基础设施代码的一部分),请参阅Steve Gordon 博客中的这些示例,这些示例使用Context
-based方法。