Обработчик необработанных исключений в .NET 1.1

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

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
28
0
4 613
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

BTW, on my 1.1 machine the example from MSDN does have the expected output; it's just that the second line doesn't show up until after you've attached a debugger (or not). In v2 we've flipped things around so that the UnhandledException event fires before the debugger attaches, which seems to be what most people expect.

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

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

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

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

Ответ принят как подходящий

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

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

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

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

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

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

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

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

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

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

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

Контактные лица в случае необработанного исключения:

  • Обработчик исключений Windows Forms.
  • Переключатель реестра JIT-отладки 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);

Другие вопросы по теме