2012-09-28 1 views
2

메인 애플리케이션 스레드가 아닌 다른 스레드에서 Throw 된 예외가 DispatcherUnhandledException 이벤트 핸들러에 의해 포착되지 않는 것으로 나타났습니다. 그래서 수동처럼 그들을 던져 있습니다Task 객체의 액션에 의해 던져지는 예외를 내 메인 애플리케이션 스레드에서 자동으로 잡아낼 수 있습니까?

Task.Factory.StartNew(() => 
{ 
    throw new Exception("oops! something went wrong..."); 

}).ContinueWith((task) => 
{ 
    if (task.IsFaulted) 
    { 
     App.Current.Dispatcher.Invoke(new Action(() => 
     { 
      throw task.Exception.InnerExceptions.First(); 
     })); 
    } 
}); 

그러나, 내가 만드는 모든 단일 작업에 위의 ContinueWith 방법을 추가 할 수 없습니다. 차라리 자동으로 처리 할 수있는 방법이 있습니다. 그러나, 작업 클래스와는 달리

TaskEx.StartNew(() => 
{ 
    // do something that may cause an exception 
}).ContinueWith((task) => 
{ 
    // then do something else that may cause an exception 
}).ContinueWith((task) => 
{ 
    // then do yet something else that may cause an exception 
}); 

:

/// <summary> 
/// Extends the System.Threading.Tasks.Task by automatically throwing the first exception to the main application thread. 
/// </summary> 
public class TaskEx 
{ 
    public Task Task { get; private set; } 

    private TaskEx(Action action) 
    { 
     Task = Task.Factory.StartNew(action).ContinueWith((task) => 
     { 
      ThrowTaskException(task); 
     }); 
    } 

    public static TaskEx StartNew(Action action) 
    { 
     if (action == null) 
     { 
      throw new ArgumentNullException(); 
     } 

     return new TaskEx(action); 
    } 

    public TaskEx ContinueWith(Action<Task> continuationAction) 
    { 
     if (continuationAction == null) 
     { 
      throw new ArgumentNullException(); 
     } 

     Task = Task.ContinueWith(continuationAction).ContinueWith((task) => 
     { 
      ThrowTaskException(task); 
     }); 

     return this; 
    } 

    private void ThrowTaskException(Task task) 
    { 
     if (task.IsFaulted) 
     { 
      App.Current.Dispatcher.Invoke(new Action(() => 
      { 
       throw task.Exception.InnerExceptions.First(); 
      })); 
     } 
    } 
} 

가 지금은 간단하게 다음과 같은 코드를 사용할 수 있습니다 (작업 클래스와 동일) :

답변

2

다음 클래스는 이러한 문제를 해결 이러한 스레드 중 하나에서 던져진 예외는 DispatcherUnhandledException 이벤트 처리기에서 자동으로 catch됩니다.

관련 문제