2016-07-08 2 views
0

Почему следующий сбой при запуске внутри консольного приложения вместо того, чтобы бросать AggregateException и быть пойманным внешним try/catch?Почему исключение в async Parallel.ForEach приводит к сбою приложения?

Я упростил вариант использования для 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(); 
+0

Я не вижу никакого кода, который ловит исключение в async-части ваших задач, что действительно приводит к незаслуженным исключениям и прекращению процесса ... Боковое замечание: я не совсем уверен, зачем вам 'Parallel.ForEach' для запуска нескольких задач, когда вам все равно, как они заканчиваются ... Вы можете найти «C# fire-and-forget async», если вам действительно нужен код, похожий на один в этом сообщении. –

+0

@AlexeiLevenkov, я думаю, мой вопрос ... почему мне нужно поймать его внутри цикла просто потому, что он асинхронный? Когда это синхронно, это не требует этого. Кроме того, это не для огня и забыть, в моем фактическом коде я делаю вызов функции, которая является ожидаемой, я просто упростил использование для краткости с пустой задачей. –

+3

Не смешивайте 'Parallel.ForEach' с' async/await' http://stackoverflow.com/questions/11564506/nesting-await-in-parallell-foreach – MickyD

ответ

4

Как уже упоминалось в комментариях, you shouldn't mix async and Parallel.ForEach, они не работают вместе.

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

+0

Спасибо за объяснение, это очень полезно. –

 Смежные вопросы

  • Нет связанных вопросов^_^