异步Task.WhenAll超时
在新的异步dotnet 4.5库中有一种方法可以在Task.WhenAll
方法上设置超时。 我想要获取多个源并在5秒后停止并跳过未完成的源。
您可以使用Task.WhenAny()
将生成的Task
与Task.Delay()
使用:
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(timeout));
如果您想在超时情况下收获完成的任务:
var completedResults =
tasks
.Where(t => t.Status == TaskStatus.RanToCompletion)
.Select(t => t.Result)
.ToList();
我认为一个更清晰,更强大的选项,也是异常处理的权利,将使用Task.WhenAny
与每个任务一起使用一个超时任务,完成所有已完成的任务并过滤出超时任务,并使用await Task.WhenAll()
而不是Task.Result
来收集所有结果。
这是一个完整的工作解决方案:
static async Task<TResult[]> WhenAll<TResult>(IEnumerable<Task<TResult>> tasks, TimeSpan timeout)
{
var timeoutTask = Task.Delay(timeout).ContinueWith(_ => default(TResult));
var completedTasks =
(await Task.WhenAll(tasks.Select(task => Task.WhenAny(task, timeoutTask)))).
Where(task => task != timeoutTask);
return await Task.WhenAll(completedTasks);
}
查看Microsoft基于任务的异步模式概述中的“Early Bailout”和“Task.Delay”部分。
提前救市。 由t1表示的操作可以在另一个任务t2中分组为WhenAny,并且我们可以等待WhenAny任务。 t2可能代表超时,取消或其他一些信号,这会导致在完成t1之前完成WhenAny任务。
链接地址: http://www.djcxy.com/p/39527.html