我想使用Polly执行以下操作:尝试在很短的时间内发出请求。如果失败,请重试超时。
我看到Retry
可以这样访问retryCount
:
Policy
.Handle<SomeExceptionType>()
.Retry(3, (exception, retryCount, context) =>
{
// do something
});
而且我看到
Timeout
可以指定int
或TimeSpan
,如下所示:Policy.Timeout(TimeSpan.FromMilliseconds(2500))
我什至看到您可以将函数传递给超时,如下所示:
Policy.Timeout(() => myTimeoutProvider)) // Func<TimeSpan> myTimeoutProvider
Func
选项似乎是最有前途的,但是在哪里可以访问重试计数?将状态保留在策略之外很容易,但是如果我想以线程安全的方式共享策略,那是很危险的。有什么建议吗?
最佳答案
您可以使用Polly Context
在执行所涉及的不同策略之间传递状态数据。 Polly Context
的唯一实例随每次Polly执行一起流动,因此这是完全线程安全的。
关于此技术的更多详细信息in this blog post。
例如:
const string RetryCountKey = "RetryCount";
RetryPolicy retryStoringRetryCount = Policy
.Handle<Exception>()
.Retry(3, (exception, retryCount, context) =>
{
Console.WriteLine("Storing retry count of " + retryCount + " in execution context.");
context[RetryCountKey] = retryCount;
});
TimeoutPolicy timeoutBasedOnRetryCount = Policy
.Timeout(context =>
{
int tryCount;
try
{
tryCount = (int) context[RetryCountKey];
}
catch
{
tryCount = 0; // choose your own default for when it is not set; also applies to first try, before any retries
}
int timeoutMs = 25 * (tryCount + 1);
Console.WriteLine("Obtained retry count of " + tryCount + " from context, thus timeout is " + timeoutMs + " ms.");
return TimeSpan.FromMilliseconds(timeoutMs);
});
PolicyWrap policiesTogether = retryStoringRetryCount.Wrap(timeoutBasedOnRetryCount);
(注意:当然可以使此^更加简洁。此处列出以提供最大的清晰度。)
这是live dotnetfiddle example。