我想使用 Polly 执行以下操作:尝试超时时间很短的请求。如果失败,请使用更长的超时时间重试。
我看到Retry可以这样访问retryCount:
Policy
.Handle<SomeExceptionType>()
.Retry(3, (exception, retryCount, context) =>
{
// do something
});
Run Code Online (Sandbox Code Playgroud)
我看到Timeout可以指定一个intor TimeSpan,如下所示:
Policy.Timeout(TimeSpan.FromMilliseconds(2500))
Run Code Online (Sandbox Code Playgroud)
我什至看到您可以将函数传递给超时,如下所示:
Policy.Timeout(() => myTimeoutProvider)) // Func<TimeSpan> myTimeoutProvider
Run Code Online (Sandbox Code Playgroud)
该Func选项似乎最有前途,但它可以从哪里访问重试计数?将状态保持在策略之外是很诱人的,但是如果我想以线程安全的方式共享策略,这很危险。
有什么建议吗?
您可以使用 PollyContext在执行中涉及的不同策略之间传递状态数据。Context每次执行Polly时都会有一个独特的 Polly 实例,因此这完全是线程安全的。
例如:
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);
Run Code Online (Sandbox Code Playgroud)
(注意:当然这个 ^ 可以做得更简洁。为了最大程度的清晰起见,在这里列出。)
这是一个实时的 dotnetfiddle 示例。
| 归档时间: |
|
| 查看次数: |
904 次 |
| 最近记录: |