Вопрос

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

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

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

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

Это было полезно?

Решение

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

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

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

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

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

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

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

Редактировать:Можно отключить (= взломать) механизм отчетов об ошибках, встроенный в Windows, чтобы обязательное диалоговое окно "сбой и запись" не отображалось при выходе вашего приложения из строя.Однако это становится эффективным для ВСЕ приложения в системе, а не только ваши собственные.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

AppDomain.CurrentDomain.UnhandledException += new
System.UnhandledExceptionEventHandler(CatchClrExceptions);

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

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

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

Это приложение Windows Forms.Исключения, которые перехватываются приложением.ThreadException работает нормально, и я не получаю уродливое сообщение.Поле NET exception (ОК прекратить, Отмена для отладки?кто это придумал??).

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top