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();
}));
}
}
}
가 지금은 간단하게 다음과 같은 코드를 사용할 수 있습니다 (작업 클래스와 동일) :