【发布时间】:2014-10-30 07:05:06
【问题描述】:
据我所知,有两种可能的模式来实现基于任务的异步方法的超时:
内置超时
public Task DoStuffAsync(TimeSpan timeout)
这种方法更难实现,因为为整个调用堆栈实现一个全局超时并不容易。例如,Web API 控制器接收到一个 HTTP 请求并调用DoStuffAsync,调用者希望全局超时为 3 秒。
也就是说,每个内部异步方法调用都需要接收已使用时间的减法...
没有内置超时
public Task DoStuffAsync(CancellationToken cancellationToken)
..........
CancellationTokenSource cancellationSource = new CancellationTokenSource();
Task timeoutTask = Task.Delay(3000);
if(await Task.WhenAny(DoStuffAsync(cancellationTokenSource), timeoutTask) == timeoutTask)
{
cancellationSource.Cancel();
throw new TimeoutException();
}
这似乎是最可靠和最容易实现的模式。第一个调用者定义了一个全局超时,如果它超时,所有挂起的操作都将被取消。此外,它为直接调用者提供了一个取消令牌,内部调用将共享相同的取消令牌引用。因此,如果顶级调用者超时,它将能够取消任何工作线程。
整个问题
我是否缺少任何模式,或者如果我使用无内置超时开发 API,我的方法是否正确?
【问题讨论】:
标签: c# .net design-patterns asynchronous async-await