Почему исключение в асинхронном 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 ответ

Решение

Как уже упоминалось в комментариях, вы не должны смешивать async а также Parallel.ForEach они не работают вместе.

То, что вы наблюдаете, является одним из последствий этого: лямбда скомпилирована как async void метод и когда async void метод бросает, исключение перебрасывается на его SynchronizationContext, который обычно вылетает из приложения.

Другие вопросы по тегам