2016-01-04 114 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. 
      } 
     }); 
    } 
}