Task.Run中的全局错误处理

时间:2016-01-04 17:19:23

标签: c# wpf error-handling

我有一个wpf c#app。

我通常使用全局错误处理程序来捕获所有错误:

private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
    try
    {
        Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => Xceed.Wpf.Toolkit.MessageBox.Show(e.Exception.ToString(), "Error",
          MessageBoxButton.OK, MessageBoxImage.Error)));
        e.Handled = true;
        InformedWorkerDataService.Common.Shared.RecordMessage(e.Exception.ToString(), true);
    }
    finally { }
}

但是,如果启动一个task.run'代码'并且它抛出一个错误,然后我发现错误没有被捕获:

Task.Run(() =>
{
    throw and error here    
});

所以我必须放一个' Try-Catch'抓住它的事情:

Task.Run(() =>
{
    try
    {
        throw an error here
    }
    catch (Exception ex)
    {
        do  something with error
    }
});

〜这会破坏具有全局错误处理程序的对象

我该怎么办?

2 个答案:

答案 0 :(得分:2)

您可以使用<{3}}事件

TaskScheduler.UnobservedTaskException += (s, e) => {
    e.Exception  //The Exception that went unobserved.
    e.SetObserved(); //Marks the Exception as "observed," thus preventing it from triggering exception escalation policy which, by default, terminates the process.
};
  

当出现故障的任务未被观察到的异常即将触发异常升级策略时,默认情况下会终止该进程。

     

此应用程序域范围事件提供了一种机制,可防止异常升级策略(默认情况下终止进程)触发

答案 1 :(得分:1)

正如我对接受的答案的评论中提到的那样,TaskScheduler.UnobservedTaskException并不保证在被抛出的情况下实时触发。这意味着使用此处理程序进行用户通知可能会非常混乱,因为用户操作和错误通知不会同步发生。对于用户驱动的“意想不到的&#39;任务异常,您可以创建如下的帮助方法,并使用TaskEx.Run而不是Task.Run

public static class TaskEx
{
    public static Task Run(Action function)
    {
        return Task.Run(() =>
        {
            try
            {
                function();
            }
            catch (Exception ex)
            {
                TraceEx.TraceException(ex);
                //Dispatch your MessageBox etc.
            }
        });
    }
}