WaitAll vs WaitAny

时间:2017-03-16 11:55:40

标签: c# asynchronous async-await task-parallel-library

我对WaitAllWaitAny感到有点困惑。我试图获得异常,但是当我WaitAll时它会返回异常,但是当使用WaitAny返回任何内容时,必要的是,如果任何任务完成了工作,那就是他们的任何替换{{1} }。 WaitAny()WaitAll是不同的,因为我不想让所有任务完成。喜欢

WhenAll

3 个答案:

答案 0 :(得分:4)

这称为Unobserved Exception,这基本上意味着Task Parallel Library(TPL)ThreadPool中新创建的线程中的异常未被其他线程捕获或如上述链接所述:

  

虽然未观察到的异常仍将导致   要引发的UnobservedTaskException事件(不这样做会是一个   破坏更改),默认情况下进程不会崩溃。相反,   异常将在事件发生后最终被吃掉,   无论事件处理程序是否遵守该异常。

这意味着当使用WaitAny()时,如果其中一个任务完成而没有任何异常,则不会捕获其他任务中的异常。

答案 1 :(得分:3)

也许你想要这样的东西,请注意,这会使用Task-based Asycnronous Pattern

public static Task<Task[]> WhenAllOrFirstException(params Task[] tasks)
{
    var countdownEvent = new CountdownEvent(tasks.Length);
    var completer = new TaskCompletionSource<Task[]>();

    Action<Task> onCompletion = completed =>
        {
            if (completed.IsFaulted && completed.Exception != null)
            {
                completer.TrySetException(completed.Exception.InnerExceptions);
            }

            if(countdownEvent.Signal() && !completer.Task.IsCompleted)
            {
                completer.TrySetResult(tasks);
            }
        };

    foreach(var task in tasks)
    {
        task.ContinueWith(onCompletion)
    }

    return completer.Task;
}

答案 2 :(得分:0)

您的WaitAny实现会抛出错误,这取决于首先完成的任务。 WaitAny不等到更宽松的任务(在大多数情况下它会t2)完成 - 所以它不会从中获得异常。

<强>更新

确实WaitAny不会返回此处描述的任何错误Task.WhenAny and Unobserved Exceptions