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

так что я должен поставить 'Try-поймать' вещь, чтобы захватить его:

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

~ который Defe ats объект с глобальным обработчиком ошибок

Что делать?

+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 не garenteed, чтобы стрелять в реальном времени, за исключением того, чтобы быть брошенным. Это означает, что использование этого обработчика для уведомления пользователя может быть довольно запутанным, поскольку уведомление пользователя и уведомление об ошибке не произойдет синхронно. Для управляемого пользователя обработки «неожиданных» исключений задач, вы можете создать вспомогательные методы, как показано ниже, и использовать 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. 
      } 
     }); 
    } 
} 
Смежные вопросы