使用 Polly 与 Task.TimeoutAfter 相反
如何使用 Polly 来代替 TimeoutAfter
?
我想在下面的代码中使用 Polly,而不是 TimeoutAfter
:
public async Task StartAsync()
{
await _webSocket.ConnectAsync(_uri, CancellationToken.None).TimeoutAfter(OpenTimeoutMs).ConfigureAwait(false);
...
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None).TimeoutAfter(CloseTimeoutMs);
}
public static async Task TimeoutAfter(this Task task, TimeSpan timeout)
{
try
{
await task.WaitAsync(timeout).ConfigureAwait(false);
}
catch (TimeoutException ex)
{
throw new TimeoutException($"Task timed out after {timeout}");
}
}
我的想法(不确定我是否正确)
为了让 Polly 处理事情,我需要传递一个 CancellationToken
> 到 StartAsync
并将 CancellationToken.None
替换为它。
这是我的想法,不知道对不对。这就是我问这个问题的原因。
var timeoutPolicy = Policy
.Handle<TimeoutException>()
.TimeoutAsync(TimeSpan.FromMilliseconds(timeoutMs), TimeoutStrategy.Optimistic,
(context, timeSpan, task, ex) =>
{
Console.WriteLine($"Task timed out after {timeSpan.TotalSeconds} seconds");
return Task.CompletedTask;
});
await retryPolicy.ExecuteAsync(async (ct) =>
{
await client.StartAsync(ct);
}, CancellationToken.None);
// changed the method to accept CancellationToken
public async Task StartAsync(CancellationToken ct = default)
{
await _webSocket.ConnectAsync(_uri, ct).ConfigureAwait(false);
...
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", ct).ConfigureAwait(false);
}
How do I use Polly in oppose to TimeoutAfter
?
I want to use Polly in the following code instead of TimeoutAfter
:
public async Task StartAsync()
{
await _webSocket.ConnectAsync(_uri, CancellationToken.None).TimeoutAfter(OpenTimeoutMs).ConfigureAwait(false);
...
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None).TimeoutAfter(CloseTimeoutMs);
}
public static async Task TimeoutAfter(this Task task, TimeSpan timeout)
{
try
{
await task.WaitAsync(timeout).ConfigureAwait(false);
}
catch (TimeoutException ex)
{
throw new TimeoutException(quot;Task timed out after {timeout}");
}
}
My thoughts (not sure if I'm correct)
In order Polly to handle things, I need to pass a CancellationToken
to StartAsync
and replace CancellationToken.None
with it.
This is what I think, I don't know if it's correct or not. That's why I ask the question.
var timeoutPolicy = Policy
.Handle<TimeoutException>()
.TimeoutAsync(TimeSpan.FromMilliseconds(timeoutMs), TimeoutStrategy.Optimistic,
(context, timeSpan, task, ex) =>
{
Console.WriteLine(quot;Task timed out after {timeSpan.TotalSeconds} seconds");
return Task.CompletedTask;
});
await retryPolicy.ExecuteAsync(async (ct) =>
{
await client.StartAsync(ct);
}, CancellationToken.None);
// changed the method to accept CancellationToken
public async Task StartAsync(CancellationToken ct = default)
{
await _webSocket.ConnectAsync(_uri, ct).ConfigureAwait(false);
...
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", ct).ConfigureAwait(false);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的
TimeoutAfter
扩展方法会应用两次,分别针对ConnectAsync
和CloseAsync
方法。这意味着每个方法调用都有一个“本地”超时。在您的 Polly 版本中,您定义了“全局”/“总体”超时,其中包括从
ConnectAsync
到CloseAsync
的所有内容。因此,这两个版本不相同相同。
顺便说一句,您的代码有一些问题:
TimeoutAsync
不能有Handle
子句retryPolicy
在此范围内未定义您可以替换您的
TimeoutAfter
代码以利用 Polly:CancellationToken
并返回Task
的函数ExecuteAsync
调用中,您“结合"TimeoutPolicy
和用户取消令牌令牌
首先请求取消,则ExecuteAsync
将抛出TaskCanceledException
ExecuteAsync
将抛出TimeoutRejectedException
,该异常会转换为OperationCanceledException
该方法的用法如下所示:
Your
TimeoutAfter
extension method is applied twice, separately for theConnectAsync
and for theCloseAsync
methods. It means that each method call has a "local" timeout.In your Polly version you have defined a "global" / "overarching" timeout which includes everything from
ConnectAsync
tillCloseAsync
.So, the two versions are not identical.
BTW your code have some problems:
TimeoutAsync
can't have aHandle
clauseretryPolicy
is not defined in this scopeYou can replace your
TimeoutAfter
code to this to utilize Polly:CancellationToken
and returns aTask
ExecuteAsync
call you "combine" theTimeoutPolicy
and the user cancellation tokentoken
asks for cancellation first thenExecuteAsync
will throw aTaskCanceledException
ExecuteAsync
will throw aTimeoutRejectedException
which is translated to anOperationCanceledException
The usage of this method looks like this: