异步等待 Task<T>超时完成 [英] Asynchronously wait for Task&lt;T&gt; to complete with timeout

查看:29
本文介绍了异步等待 Task<T>超时完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想等待 Task 完成并带有一些特殊规则:如果 X 毫秒后仍未完成,我想向用户显示一条消息.如果 Y 毫秒后仍未完成,我希望自动请求取消.

I want to wait for a Task<T> to complete with some special rules: If it hasn't completed after X milliseconds, I want to display a message to the user. And if it hasn't completed after Y milliseconds, I want to automatically request cancellation.

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

I can use Task.ContinueWith to asynchronously wait for the task to complete (i.e. schedule an action to be executed when the task is complete), but that doesn't allow to specify a timeout. I can use Task.Wait to synchronously wait for the task to complete with a timeout, but that blocks my thread. How can I asynchronously wait for the task to complete with a timeout?

推荐答案

这个怎么样:

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

这里是 一篇很棒的博客文章Crafting a Task.TimeoutAfter Method"(来自 MS Parallel Library 团队)提供有关此类事情的更多信息.

补充:应对我的回答发表评论的请求,这里有一个扩展的解决方案,其中包括取消处理.请注意,将取消传递给任务和计时器意味着在您的代码中可以通过多种方式体验取消,您应该确保测试并确信您正确处理了所有这些.不要随意选择各种组合,并希望您的计算机在运行时做正确的事情.

Addition: at the request of a comment on my answer, here is an expanded solution that includes cancellation handling. Note that passing cancellation to the task and the timer means that there are multiple ways cancellation can be experienced in your code, and you should be sure to test for and be confident you properly handle all of them. Don't leave to chance various combinations and hope your computer does the right thing at runtime.

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
}

这篇关于异步等待 Task<T>超时完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆