为什么异步Parallel.ForEach中的异常会使应用程序崩溃?

时间:2016-07-08 00:44:37

标签: c# exception task-parallel-library parallel.foreach

如果在控制台应用程序中运行而不是抛出AggregateException并被外部try/catch捕获,为什么会发生以下崩溃?

为简洁起见,我简化了await的用例,但在相关代码中,我确实尝试执行等待Task的重要性。

var list = new List<string>() {"Error"};

        try
        {
            Parallel.ForEach(list, new ParallelOptions()
            {
                MaxDegreeOfParallelism = 8
            }, async listEntry =>
            {
                await Task.Delay(5000);
                throw new Exception("Exception");
            });
        }
        catch (Exception ex)
        {
            //never hits, the application crashes
        }

        Console.ReadLine();

我注意到以下内容不会导致应用程序失败,并且确实发现了异常,但我不明白这两个上下文的根本不同之处是什么:

var list = new List<string>() {"Error"};

        try
        {
            Parallel.ForEach(list, new ParallelOptions()
            {
                MaxDegreeOfParallelism = 8
            }, listEntry =>
            {

                throw new Exception("Exception");
            });
        }
        catch (Exception ex)
        {
            //exception is caught, application continues
        }

        Console.ReadLine();

1 个答案:

答案 0 :(得分:5)

正如评论中已经提到的you shouldn't mix async and Parallel.ForEach,他们不能一起工作。

您正在观察的结果之一是:lambda被编译为async void方法,当async void方法抛出时,异常会在其{{1}上重新抛出通常会使应用程序崩溃。