我正在尝试使用 Polly 和 Refit 实现重试/超时过程来访问 Web 服务。我有 10 秒的超时策略(Polly.Timeout.TimeoutRejectedException on timeout)
。我有 2 次尝试的重试策略。我有一个userCancellationToken
可以被用户取消的。如果我没有设置 Polly 超时策略,客户端默认超时 100 秒后System.IO.IOException
虽然这段代码基本上可以工作,但我有一些问题:
1)我的代码大部分是正确的吗?
2)如果我的超时时间为 10 秒,并且我强制我的服务器在 15 秒内回答,作为超时测试,此代码正确执行 3 次尝试,每次 10 秒然后失败,但几秒钟后我显示 3“成功后。 ..”,这意味着任务仍在运行并等待数据,即使 Polly 取消了它。如何取消正在运行的任务?
3)如果我的服务器无法访问,我会System.Net.Sockets.SocketException
在 4 秒后得到一个。如何减少此超时?
var timeOutPolicy = Policy
.TimeoutAsync(
10,
TimeoutStrategy.Pessimistic);
var retryPolicy = Policy
.Handle<Exception>()
.RetryAsync(2, (exception, attempt) =>
{
sw.Stop();
progress.Report($"Error after {sw.Elapsed}");
progress.Report($"New attempt {attempt}");
if (exception.InnerException is System.Net.Sockets.SocketException)
{
progress.Report("Catched: SocketException (No server running or not reachable)");
}
if (exception.InnerException is System.IO.IOException)
{
progress.Report("Catched: IOException (normal timeout)");
}
if (exception is Polly.Timeout.TimeoutRejectedException)
{
progress.Report("Catched: Polly Exception (timeout set by Polly)");
}
if (exception.InnerException is ApiException) progress.Report("Catched: ApiException");
});
var policyWrap = Policy.WrapAsync(retryPolicy, timeOutPolicy);
try
{
await policyWrap.ExecuteAsync(async (ct) =>
{
sw.Restart();
progress.Report("Execute");
var api = RestService.For<ICTServerApi>("http://localhost:3105/json/reply/ReqUtenti");
respUtenti = await api.GetUtentiAsync(reqUtenti, userCancellationToken).ConfigureAwait(false);
sw.Stop();
progress.Report($"Success after {sw.Elapsed}");
}, userCancellationToken).ConfigureAwait(false);
}
谢谢!