异步等待任务< T>完成与超时任务、LT、GT

由网友(无敌呆萌帅)分享简介:I 想等待任务< T> 以完成一些特殊的规则:如果它不是X毫秒后完成的,我 要显示的消息给用户。并且如果它没有ý毫秒后完成的,我 希望自动请求取消的I 可使用 Task.ContinueWith 异步等待任务完成(即 安排一个动作时,任务完成后要执行)...

I 想等待任务< T> 以完成一些特殊的规则: 如果它不是X毫秒后完成的,我 要显示的消息给用户。 并且如果它没有ý毫秒后完成的,我 希望自动请求取消的

I 可使用 Task.ContinueWith 异步等待任务完成(即 安排一个动作时,任务完成后要执行),但不允许指定超时。 我可以使用 Task.Wait 同步地等待任务完成与超时,但块我的线程。 我怎么可以异步等待任务完成与超时?

解决方案

这个怎么样:

  INT超时= 1000;
变种任务= SomeOperationAsync();
如果(等待Task.WhenAny(任务,Task.Delay(超时))==任务){
    //任务中的超时完成
} 其他 {
    //超时逻辑
}
 

而这里的一个伟大的博客文章制作一个Task.TimeoutAfter法(从MS并行库团队)对这种事情的更多信息。

添加:在我的答案评论的要求,这里是一个扩展的解决方案,其中包括取消处理。请注意,通过取消该任务和计时器意味着有多种方法消除可以体验到code,你应该确保测试和自信,你妥善处理所有的人。不要让侥幸心理的各种组合,并希望你的电脑做正确的事在运行时。

  INT超时= 1000;
VAR任务= SomeOperationAsync(的CancellationToken);
如果(等待Task.WhenAny(任务,Task.Delay(超时的CancellationToken))==任务)
{
    //任务中的超时完成。
    //考虑到该任务可能会出现故障或被取消。
    //我们再等待,这样任何异常/取消被重新抛出的任务。
    等待任务;

}
其他
{
    //超时/取消逻辑
}
 

今天刚刚在steam下完了gta5 可是却没弹出来安装程序 而是让我再下一遍为

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.

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?

解决方案

How about this:

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

And here's a great blog post "Crafting a Task.TimeoutAfter Method" (from MS Parallel Library team) with more info on this sort of thing.

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
}

阅读全文

相关推荐

最新文章