Я поддерживаю приложение .NET 1.1, и одна из моих задач - убедиться, что пользователь не видит никаких недружественных уведомлений об ошибках.
Я добавил обработчики к Application.ThreadException и AppDomain.CurrentDomain.UnhandledException, которые действительно вызываются. Моя проблема в том, что стандартный диалог ошибок CLR все еще отображается (до вызова обработчика исключений).
Джефф рассказывает об этой проблеме в своем блоге здесь и здесь. Но решения нет. Итак, каков стандартный способ обработки неперехваченных исключений в .NET 1.1 и отображения удобного диалогового окна?
Ответ Джеффа был отмечен как правильный, потому что предоставленная им ссылка содержит наиболее полную информацию о том, как сделать то, что требуется.





Это консольное приложение или приложение 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 зависит от:
Поведение по умолчанию для необработанных исключений:
Контактные лица в случае необработанного исключения:
Встроенная обработка исключений Windows Form по умолчанию выполняет следующие действия:
Вы можете отключить последнее поведение, установив jitDebugging = true в App.Config. Но помните, что это может быть ваш последний шанс остановить завершение работы приложения. Итак, следующим шагом для перехвата необработанного исключения является регистрация для события Application.ThreadException, например:
Application.ThreadException += new
Threading.ThreadExceptionHandler(CatchFormsExceptions);
Обратите внимание на параметр реестра DbgJitDebugLaunchSetting в разделе HKEY_LOCAL_MACHINE \ Software.NetFramework. Это одно из трех значений, о которых я знаю:
В Visual Studio перейдите в меню Инструменты → Опции → Отладка → JIT, чтобы установить для этого ключа значение 0 или 2. Но значение 1 обычно лучше всего на компьютере конечного пользователя. Обратите внимание, что этот раздел реестра применяется до события необработанного исключения среды CLR.
Это последнее событие - ваш последний шанс зарегистрировать необработанное исключение. Он срабатывает до того, как ваши блоки finally будут выполнены. Вы можете перехватить это событие следующим образом:
AppDomain.CurrentDomain.UnhandledException += new
System.UnhandledExceptionEventHandler(CatchClrExceptions);