Полли не обеспечивает перегрузку .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 , показывающие, как retryCount
передается в качестве входного параметра делегату onRetry
, который можно настроить в политике.Дополнительные примеры здесь .
Для пользователей, которые хотят получить общее количество повторных попыток, использованных для успешного выполнения операции, в обобщенном виде - скажем, для телеметрии как части некоторой общей обработки-отправкикод инфраструктуры - см. эти примеры в блоге Стива Гордона , в котором используется подход Context
.