Каково различие между Приложением. ThreadException и AppDomain. CurrentDomain. UnhandledException?

Хорошо, это - легкое:

  • Между чем различие Application.ThreadException и
    AppDomain.CurrentDomain.UnhandledException?

  • Я должен обработать обоих?

Спасибо!

103
задан serhio 18 May 2010 в 21:01
поделиться

4 ответа

Application.ThreadException специфичен для Windows Forms. Winforms запускает обработчики событий в ответ на сообщения, отправленные ему Windows. Например, событие Click, я уверен, что вы их знаете. Если такой обработчик событий бросает исключение, то внутри цикла сообщений Winforms есть обратная остановка, которая ловит это исключение.

Эта блокировка запускает событие Application.ThreadException. Если вы не переопределите его, пользователь получит ThreadExceptionDialog. Что позволит ему проигнорировать исключение и продолжить выполнение вашей программы. Не самая лучшая идея btw.

Вы можете отключить это поведение, вызвав Application.SetUnhandledExceptionMode() в методе Main() в Program.cs. Без этого бэк-останова происходит обычное дело, когда поток умирает от необработанного исключения: AppDomain.UnhandledException запускается и программа завершает работу.

Fwiw: "ThreadException" было очень плохим выбором названия. Оно не имеет никакого отношения к потокам.

96
ответ дан 24 November 2019 в 04:21
поделиться

OK - Передо мной стоял бит кода из msdn, который довольно понятен:

public static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new 
        ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

    // Set the unhandled exception mode to force all Windows Forms 
    // errors to go through our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException +=
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    // Runs the application.
    Application.Run(new ErrorHandlerForm());
}
18
ответ дан 24 November 2019 в 04:21
поделиться

Дело в том, что ThreadException возникает из-за проблемы с вашим потоком, Необработанное исключение сбрасывается, если вы выбрасываете исключение, которое не обрабатывается.

Простой способ вызвать второе - создать приложение без попыток... поймать блоки и бросить исключение.

Теперь, если вам нужна страховка, вы можете обрабатывать их оба, однако, если вы правильно перехватываете и обрабатываете исключения , то вам не нужен обработчик UnhandledException , так как это что-то вроде catch all.

0
ответ дан 24 November 2019 в 04:21
поделиться

В приложениях, использующих Windows Forms, необработанные исключения в главном потоке приложения вызывают событие Application.ThreadException . Если это событие обработано, поведение по умолчанию таково, что необработанное исключение не завершает работу приложения, хотя приложение остается в неизвестном состоянии. В этом случае событие UnhandledException не поднимается. Это поведение можно изменить с помощью файла конфигурации приложения или с помощью метода Application.SetUnhandledExceptionMode для изменения режима на UnhandledExceptionMode.ThrowException перед подключением обработчика события ThreadException. Это относится только к основному потоку приложения. Событие UnhandledException поднимается для необработанных исключений, брошенных в других потоках.

Начиная с Visual Studio 2005, Visual Basic предоставляет еще одно событие для необработанных исключений в главном потоке приложения - WindowsFormsApplicationBase.UnhandledException. Это событие имеет объект аргументов события с тем же именем, что и объект аргументов события, используемый AppDomain.UnhandledException, но с другими свойствами. В частности, этот объект аргументов события имеет свойство ExitApplication, которое позволяет приложению продолжить работу, игнорируя необработанное исключение (и оставляя приложение в неизвестном состоянии). В этом случае событие AppDomain.UnhandledException не поднимается.

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

Для отлова исключений, возникающих в потоках, не созданных и не принадлежащих Windows Forms, используйте AppDomain.UnhandledException. Он позволяет приложению записать в журнал информацию об исключении до того, как системный обработчик по умолчанию сообщит об исключении пользователю и завершит работу приложения.
Обработка этого исключения не предотвращает завершение работы приложения.
Максимум, что может быть сделано (данные программы могут быть повреждены, если исключения не обрабатываются) - это сохранение данных программы для последующего восстановления. После этого домен приложения выгружается и приложение завершается.

Начиная с .NET 4, это событие не вызывается для исключений, повреждающих состояние процесса, таких как переполнение стека или нарушение доступа, если только обработчик события не критичен к безопасности и не имеет атрибут HandleProcessCorruptedStateExceptionsAttribute.

Более подробную информацию см. в MSDN.

34
ответ дан 24 November 2019 в 04:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: