Необработанный обработчик исключений в .NET 1.1 - PullRequest
24 голосов
/ 04 августа 2008

Я поддерживаю приложение .NET 1.1, и одна из задач, с которыми мне было поручено, - убедиться, что пользователь не видит никаких недружественных уведомлений об ошибках.

Я добавил обработчики к Application.ThreadException и AppDomain.CurrentDomain.UnhandledException, которые действительно вызывают. Моя проблема заключается в том, что стандартное диалоговое окно ошибки CLR по-прежнему отображается (до вызова обработчика исключений).

Джефф рассказывает об этой проблеме в своем блоге здесь и здесь . Но нет решения. Так что же является стандартным способом в .NET 1.1 для обработки необработанных исключений и отображения удобного диалогового окна?

Ответ Джеффа был помечен как правильный ответ, поскольку предоставленная им ссылка содержит наиболее полную информацию о том, как сделать то, что требуется.

Ответы [ 5 ]

11 голосов
/ 04 августа 2008

О, в Windows Forms вы определенно должны иметь возможность заставить его работать. Единственное, на что вам следует обратить внимание - это то, что происходит в разных потоках.

У меня есть старая статья проекта Code, которая должна помочь:

Удобная обработка исключений

5 голосов
/ 20 сентября 2008

Поведение необработанного исключения в приложении Windows Forms .NET 1.x зависит от:

  • Тип нити, с которой возникло исключение
  • Произошло ли это во время обработки сообщения окна
  • Был ли отладчик подключен к процессу
  • Параметр реестра DbgJitDebugLaunchSetting
  • Флаг jitDebugging в App.Config
  • Переопределил ли вы обработчик исключений Windows Forms
  • Обрабатывали ли вы событие-исключение CLR
  • Фаза луны

Поведение необработанных исключений по умолчанию:

  • Если исключение возникает в основном потоке при прокачке оконных сообщений, оно перехватывается обработчиком исключений Windows Forms.
  • Если исключение возникает в главном потоке при прокачке оконных сообщений, оно завершает процесс приложения, если оно не перехватывается обработчиком исключений Windows Forms.
  • Если исключение возникает в потоке руководства, пула потоков или финализатора, оно проглатывается CLR.

Точки контакта для необработанного исключения:

  • Обработчик исключений Windows Forms.
  • Переключатель реестра JIT-debug DbgJitDebugLaunchSetting.
  • Событие необработанного исключения CLR.

Встроенная обработка исключений Windows Form по умолчанию делает следующее:

  • Поймает необработанное исключение, когда:
    • исключение для основного потока и отладчик не подключен.
    • исключение возникает при обработке сообщения окна.
    • jitDebugging = false в App.Config.
  • Показывает диалог для пользователя и предотвращает завершение работы приложения.

Вы можете отключить последнее поведение, установив jitDebugging = true в App.Config. Но помните, что это может быть вашим последним шансом остановить завершение работы приложения. Поэтому следующим шагом для обнаружения необработанного исключения является регистрация события Application.ThreadException, например ::

.
Application.ThreadException += new
Threading.ThreadExceptionHandler(CatchFormsExceptions);

Обратите внимание на параметр реестра DbgJitDebugLaunchSetting в HKEY_LOCAL_MACHINE \ Software.NetFramework. Это имеет одно из трех значений, о которых я знаю:

  • 0: показывает диалог пользователя с вопросом «отладка или завершение».
  • 1: позволяет исключению работать с CLR.
  • 2: запускает отладчик, указанный в разделе реестра DbgManagedDebugger.

В Visual Studio перейдите в меню Инструменты Параметры Отладка JIT , чтобы установить этот ключ на 0 или 2. Но значение 1 обычно лучше на компьютере конечного пользователя. Обратите внимание, что этот раздел реестра действует до события необработанного исключения CLR.

Последнее событие - ваш последний шанс зарегистрировать необработанное исключение. Он сработает до того, как будут выполнены ваши блоки finally. Вы можете перехватить это событие следующим образом:

AppDomain.CurrentDomain.UnhandledException += new
System.UnhandledExceptionEventHandler(CatchClrExceptions);
5 голосов
/ 04 августа 2008

AppDomain.UnhandledException - это событие , а не глобальный обработчик исключений. Это означает, что к тому времени, когда оно поднято, ваше приложение уже находится на пути к истощению, и вы ничего не можете с этим поделать, кроме выполнения очистки и регистрации ошибок.

То, что произошло за кулисами, таково: платформа обнаружила исключение, поднялась вверх по стеку вызовов, не нашла обработчиков, которые могли бы восстановиться после ошибки, поэтому не смогла определить, безопасно ли продолжать выполнение. Итак, он запустил последовательность завершения работы и вызвал это событие вежливости к вам, чтобы вы могли выразить свое уважение к уже обреченному процессу. Это происходит, когда исключение остается необработанным в главном потоке.

Нет единого решения этой ошибки. Вам необходимо поместить настоящий обработчик исключений (блок перехвата) перед всеми местами, где возникает эта ошибка, и направить его (например) в глобальный метод / класс обработчика, который определит, безопасно ли просто сообщать и продолжать, основываясь на тип исключения и / или содержание.

Редактировать: можно отключить (= взломать) механизм сообщения об ошибках, встроенный в Windows, так что обязательное диалоговое окно «сбой и запись» не отображается, когда приложение закрывается. Однако это вступает в силу для всех приложений в системе, а не только для ваших собственных.

3 голосов
/ 04 августа 2008

Это консольное приложение или приложение Windows Forms? Если это консольное приложение .NET 1.1, то, к сожалению, оно разработано - это подтверждается разработчиком MSFT во втором сообщении в блоге, на которое вы ссылались :

Кстати, на моей машине 1.1 пример из MSDN имеет ожидаемый результат; просто вторая строка не появляется, пока вы не подключите отладчик (или нет). В v2 мы перевернули вещи так, что событие UnhandledException срабатывает до того, как подключается отладчик, что, по-видимому, является тем, чего большинство людей ожидают.

Похоже, что .NET 2.0 делает это лучше (слава богу), но, честно говоря, у меня никогда не было времени, чтобы вернуться и проверить.

1 голос
/ 04 августа 2008

Это приложение Windows Forms. Исключения, перехваченные Application.ThreadException, работают нормально, и я не получаю уродливое поле исключений .NET ( OK для завершения, Отмена для отладки? ??).

Я получал некоторые исключения, которые не были пойманы этим, и заканчивал тем, что переходил к событию AppDomain.UnhandledException, которое вызывало проблемы. Я думаю, что я поймал большинство из этих исключений, и теперь я показываю их в нашем хорошем окне ошибок.

Так что мне остается только надеяться, что нет других обстоятельств, которые могли бы привести к тому, что исключения не будут обработаны обработчиком Application.ThreadException.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...