期望捕获聚合异常

Expecting to catch an Aggregate Exception

我正在尝试了解 TPL 数据流中的异常处理,以便我可以有效地处理错误。在我下面编号为 1 的评论中,我希望看到一个 AggregateException,但一切都停止了并且没有恢复。如果我删除 throw (2.) 然后 ActionBlock 继续处理,但 AggregateException 处理程序不会触发。

谁能帮忙解释一下,提高我的直觉。

也欢迎任何关于该主题的文档参考。

async Task Main()
{
    var ab = new System.Threading.Tasks.Dataflow.ActionBlock<int>(async a => {
        try
        {
            await Task.Delay(100);
            if (a == 7)
            {
                throw new Exception("Failed");
            }
            else
            {
                Console.WriteLine(a);
            }
        }
        catch (Exception ie)
        {
            Console.WriteLine(ie.Message);
            throw;  //2. This causes the actionblock to halt, removing allows block to continue
        }

    });

    for (int i = 0; i < 10; i++)
    {
        await ab.SendAsync(i);
    }
    ab.Complete();

    try
    {
        await ab.Completion;
    }
    catch (AggregateException ae)
    {
        Console.WriteLine(ae.Flatten().Message);
        // 1. Expecting to catch here.
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }
}

您看到的是 await 展开聚合异常。当您 await 完成任务时,异常将被解包并抛给一般异常捕获。但是,如果您不解包异常,那么您会看到异常作为聚合异常被捕获,如下所示:

try
{
    ab.Completion.Wait();
}
catch (AggregateException ae)
{
    Console.WriteLine("Aggregate Exception");
    // 1. Expecting to catch here.
}
catch (Exception e)
{
    Console.WriteLine("Exception Caught");
}

显然 await 完成会更好,但是这个示例向您展示了 AggregateExcpetion 在未展开时确实被捕获了。