异步Task.WhenAll超时

在新的异步dotnet 4.5库中有一种方法可以在Task.WhenAll方法上设置超时。 我想要获取多个源并在5秒后停止并跳过未完成的源。


您可以使用Task.WhenAny()将生成的TaskTask.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

上一篇: Async Task.WhenAll with timeout

下一篇: Why is the async CTP performing poorly?