Перехват необработанного исключения в отдельных потоках - PullRequest
24 голосов
/ 26 ноября 2010

Я использую следующее событие для перехвата необработанных исключений в основном потоке пользовательского интерфейса.

Application.ThreadException 

К сожалению, эти необработанные ошибки не отлавливаются в отдельных потоках.Мне известно о

AppDomain.CurrentDomain.UnhandledException

. Однако, похоже, что при запуске приложение закрывается, в отличие от первого.

Есть ли способ обработки необработанных исключений в отдельных потоках без закрытия приложения?

Ответы [ 3 ]

24 голосов
/ 26 ноября 2010

@ Ани уже ответила на ваш вопрос. Хотя я не согласен с тем, что необработанные исключения в потоках должны завершать приложения. Использование потоков обычно означает, что у вас есть какое-то серверное приложение. Снижение может привести к большому количеству злых пользователей.

Я написал небольшую статью о правильной обработке исключений: http://blog.gauffin.org/2010/11/do-not-catch-that-exception/

Вы должны всегда ловить исключения для потоков. Я обычно использую следующий шаблон:

  void ThreadMethod(object state)
  {
      try
      {
          ActualWorkerMethod();
      }
      catch (Exception err)
      {
          _logger.Error("Unhandled exception in thread.", err);
      }
  }

  void ActualWorkerMethod()
  {
      // do something clever
  }

Намного проще найти методы потока, которые не обрабатывают исключения должным образом, переместив логику в отдельный метод и просто оставив блок try / catch в методе потока.

3 голосов
/ 06 ноября 2018

Конечно, вы всегда должны обрабатывать все исключения.Но если вы в настоящее время неспособны сделать это, вы можете попробовать следующее:

Приложение вылетит / закроется после обработчика событий UnhandledException.Вы можете просто добавить задержку в обработчик событий, чтобы предотвратить это.Другие потоки без исключения (например, основной поток) могут продолжаться.Так что приложение не закроется и может продолжаться.Тем не менее, поток с исключением будет оставаться в спящем режиме.И поэтому вы можете получить «утечку памяти / потока».

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        // Log the exception, display it, etc
        Debug.WriteLine((e.ExceptionObject as Exception).Message);
        Thread.Sleep(100000000);
    }

На данный момент лучшего решения нет.Вы можете найти, чтобы изменить файл конфигурации, но я думаю, что это так же грязно: https://stackoverflow.com/a/15348736

2 голосов
/ 13 января 2011

Да, вы должны вручную перехватывать исключения в потоках.

Однако этот код:

void ThreadMethod(object state)
{
    try
    {
        ActualWorkerMethod();
    }
    catch (Exception err)
    {
        _logger.Error("Unhandled exception in thread.", err);
    }
}

void ActualWorkerMethod()
{
    // do something clever
}

можно упростить до этого, используя PostSharp :

[LogExceptions]
void ActualWorkerMethod()
{
    // do something clever
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...