2014-09-18 2 views
12

오늘 내 동료와 나는 5.0 async 방법을 제대로 C#에서 예외를 처리하는 방법을 논의하고, 한 번도 여러 작업을 기다리는 것은 런타임에서 풀어되지 않는 예외를 관찰하면 우리는 궁금. 이제 두 번째 작업은 어떻게됩니까여러 작업을 기다리는 것이 첫 번째 예외 이상의 것을 관찰합니까?

async Task ExceptionMethodAsync() 
{ 
    await Task.Yield(); 
    throw new Exception(); 
} 

async Task CallingMethod() 
{ 
    try 
    { 
     var a = ExceptionMethodAsync(); 
     var b = ExceptionMethodAsync(); 

     await Task.WhenAll(a, b); 
    } 
    catch(Exception ex) 
    { 
     // Catches the "first" exception thrown (whatever "first" means) 

    } 
} 

:

는 다음과 같은 코드를 생각해? 두 가지 모두 오류 상태에 있지만 두 번째 작업의 예외는 이제 관찰되거나 관찰되지 않습니다.

+0

모두 관찰됩니다. –

+0

책 C#에서이 문제에 대해 깊이 논의 했으므로 거기에서 답을 찾을 수 있습니다. – Matt

답변

26

Task.WhenAll은 모든 작업과 마찬가지로 모든 예외와 결합 된 AggregateException을 보유하고 있습니다. 당신이 await 같은 작업이 첫 번째 예외가 실제로 발생합니다

.

... 오류가있는 하위 작업 또는 Task.WhenAlll과 같은 결합자가 있기 때문에 하나의 작업이 여러 작업을 나타내며 둘 이상의 작업이 잘못되었을 수 있습니다. 이러한 경우, 예외 정보 (사후 디버깅에 중요 할 수 있음)를 잃지 않으려는 목적으로 여러 예외를 나타낼 수 있기를 원하므로 래퍼 유형에 대해 AggregateException을 선택했습니다.

은 ... "기다리고 있습니다", 다시 항상 첫 번째를 던지고 또는 항상을 위해, 집계을 던지는의 검색을 가진 우리가 항상 그것의 Task Exception Handling in .NET 4.5

에서 처음

을 던져 선택 점을 감안 await task; (대부분의 경우 true) 또는 task.Exception (아래 예에서와 같이)을 모두 사용하여 첫 번째를 처리하려는 경우 선택할 수 있지만 두 경우 모두 abUnobservedTaskException을 발생시키지 않습니다.

var task = Task.WhenAll(a, b); 
try 
{ 
    await task; 
} 
catch 
{ 
    Trace.WriteLine(string.Join(", ", task.Exception.Flatten().InnerExceptions.Select(e => e.Message))); 
} 
+0

catch에 'task.Exception.Handle (_ => true)'를 호출해야합니까? 아니면'await'을 사용하여 "처리됨"으로 표시된 자식 예외입니까? – jorgebg

+1

@jorgebg'Task.WhenAll'은 모든 개별 작업의 예외를 "처리"한다고 가정합니다. 'Task.WhenAll' 복합 태스크의 예외를 처리하기 만하면됩니다. 그래서 AFAIK,'Task.WhenAll (...)'충분하다. – i3arnon

관련 문제