2016-01-04 96 views
2

我有一个wpf c#应用程序。Task.Run中的全局错误处理

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

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  
}); 

,所以我必须在把“尝试捕获”的事情捕捉到它:

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

〜这防卫厅具有全局错误处理程序的对象

我该怎么办?

+2

试试['TaskScheduler.UnobservedTaskException'](https://msdn.microsoft.com/ en-us/library/system.threading.tasks.taskscheduler.unobservedtaskexception(v = vs.110).aspx)event – dkozl

+0

@dkozl cool - thanks :) –

回答

2

有一个TaskScheduler.UnobservedTaskException事件,您可以使用

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. 
}; 

当故障任务的未观测到的异常即将触发异常升级策略,其中,默认情况下,将终止该进程时发生。

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

+0

我很高兴你发布了一个答案,以便我可以接受它。我仍然需要设置:? –

+0

如果你处理你的例外,那么不是。通常我不会设置'ThrowUnobservedTaskExceptions'。如果有例外,我宁愿处理/记录它,然后将其隐藏起来。 – dkozl

+0

ok - ta。我可以在2分钟内接受你的答案。 –

1

正如我在接受答案的评论提到的,TaskScheduler.UnobservedTaskException不保证在抛出异常情况下实时触发。这意味着使用此处理程序进行用户通知可能会非常混乱,因为用户操作和错误通知不会同步发生。对于“意外”的任务异常的用户驱动的处理,你可以创建helper方法如下,并使用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. 
      } 
     }); 
    } 
}