一尘不染

异步等待任务 完成超时

c#

我想等待Task 用一些特殊规则完成:如果X毫秒后任务还没有完成,我想向用户显示一条消息。如果它在Y毫秒后仍未完成,我想自动请求cancel

我可以使用Task.ContinueWith异步地等待任务完成(即,安排在任务完成时执行的动作),但这不允许指定超时。我可以使用Task.Wait来同步等待任务完成并超时,但这会阻塞我的线程。如何异步等待任务完成并超时?


阅读 355

收藏
2020-05-19

共1个答案

一尘不染

这个怎么样:

int timeout = 1000;
var task = SomeOperationAsync();
if (await Task.WhenAny(task, Task.Delay(timeout)) == task) {
    // task completed within timeout
} else { 
    // timeout logic
}

这是一篇很棒的博客文章“制作Task.TimeoutAfter方法”(来自MS Parallel
Library团队),其中包含有关此类问题的更多信息

另外
:根据对我的答案的评论要求,这里提供了扩展的解决方案,其中包括取消处理。请注意,将取消传递给任务和计时器意味着在代码中可以采用多种方式进行取消,因此您应确保进行测试并确信自己已正确处理所有这些方法。不要错过各种组合,并希望您的计算机在运行时做正确的事情。

int timeout = 1000;
var task = SomeOperationAsync(cancellationToken);
if (await Task.WhenAny(task, Task.Delay(timeout, cancellationToken)) == task)
{
    // Task completed within timeout.
    // Consider that the task may have faulted or been canceled.
    // We re-await the task so that any exceptions/cancellation is rethrown.
    await task;

}
else
{
    // timeout/cancellation logic
}
2020-05-19