8

위의 주제에 대한 많은 질문이 있지만 새로운 질문을하기에 충분하다고 생각합니다. 나는 다음과 같은 Task을 가지고 있고 계속해서 다양한 업무를 처리하고있다. Status; TaskStatus.RanToCompletion, TaskStatus.Canceled 및 물론 AggregateException을 통해 TaskStatus.Faulted을 거쳐야한다. 그 다음에 무슨 - 거기 AggregateException의 가능성이 계속 내에서 발생되는 것으로 코드는이 모든 잘 작동하지만, 나는이 권리를하고있는 중이 야하는지 여부를 걱정TPL 및 예외 처리

Task<bool> asyncTask = Task.Factory.StartNew<bool>(() => 
    asyncMethod(uiScheduler, token, someBoolean), token); 

asyncTask.ContinueWith(task => 
{ 
    // Check task status. 
    switch (task.Status) 
    { 
     // Handle any exceptions to prevent UnobservedTaskException.    
     case TaskStatus.RanToCompletion: 
      if (asyncTask.Result) 
      { 
       // Do stuff... 
      } 
      break; 
     case TaskStatus.Faulted: 
      if (task.Exception != null) 
       mainForm.progressRightLabelText = task.Exception.InnerException.Message; 
      else 
       mainForm.progressRightLabelText = "Operation failed!"; 
     default: 
      break; 
    } 
} 

처럼 보인다?

Wait이 내 asyncTask에 없으며, 계속 진행하면 UI 스레드로 되돌아 가지 않습니다. 연속 내에서 던져진 예외를 잡으려면 반드시 이와 같은 작업을 수행해야한다는 뜻은 아닙니다.

Task parentTask = Task.Factory.startNew(() => 
    { 
     Task<bool> asyncTask = Task.Factory.StartNew<bool>(() => 
      asyncMethod(uiScheduler, token, someBoolean), token); 

     Task continueTask = asyncTask.ContinueWith(task => 
      { 
       // My continuation stuff... 
      } 

     try 
     { 
      continueTask.Wait(); 
     } 
     catch(AggregateException aggEx) 
     { 
      // Some handling here... 
     } 
    }); 

이렇게해도 작동합니까? 가장 좋은 방법은 무엇입니까?

언제나 감사합니다.

+0

실제로 AggregateException을 던졌을 때 "완료되었습니다"라는 작업을 보았습니다. 이러한 종류의 오류 처리는 작동하지 않습니다. try/catch를 사용하지 않는 이유는 무엇입니까? –

+0

백그라운드 스레드 또는 실제 연속 위임 메서드에서 호출되는 메서드를 의미합니까? – MoonKnight

답변

12

당신 AggregateException에 대한보고 당신의 대표단 내에서 기존의 시도/캐치를 사용하거나 할 수 있습니다 수있는 선행이 TaskContinuationOptions.OnlyOnFaulted 옵션을 사용하여 오류가 발생한 경우에만 지금까지 실행됩니다 특정의 ​​연속 요청에 체인. 후자의 접근 방식은 매우 깔끔한 작업 흐름을 정의 할 수있게합니다. 예 :

Task myRootTask = ....; 

myRootTask.ContinueWith(rootAntecdent => 
{ 
    // this will only be executed if the antecedent completed successfully, no need to check for faults 
}, 
TaskContinuationOptions.OnlyOnRanToCompletion); 

myRootTask.ContinueWith(rootAntecedent => 
{ 
    // this will only be executed if the antecedent faulted, observe exception and handle accordingly 
}, 
TaskContinuationOptions.OnlyOnFaulted); 
2

MSDN은이 상당히 잘 쓰여진 "방법"주제에 : here

당신은 그들이 단순히 그 때 ae.Handle(lambda)에서 처리하는 방법을 알고있는 예외를 좁히려 try/catch(AggregateException) 블록을 사용 알 앱 정지를 만들 것입니다 처리 할 수없는 왼쪽이있는 경우.

+0

나는 귀하의 링크가 제공하는 것과 같은 예를 알고 있으며, 이러한 처리 방법과 관련하여 문제가 없습니다. 내 문제는 try catch를 사용하여 전체 연속 대표를 묶지 않고 연속에서 던진 exeptions를 처리하는 방법입니다. 다시 이것은 유일한 방법 일 수 있습니다. 필자는 Microsoft 장난감 코드 모범 사례가 아닌 실제 코드에 가장 적합한 매개 변수를 알고 싶습니다. 건배. – MoonKnight

+0

+1 링크입니다. 매우 유용합니다. – SleepyBoBos

+0

OP는 Wait을 사용하지 않고이를 수행하는 방법을 알고 싶어합니다. 모든 예는 작업 대기 중입니다. 이 [http://msdn.microsoft.com/en-us/library/dd997415.aspx] 링크를 사용해보십시오. –