В чем разница между Application.ThreadException и AppDomain.CurrentDomain.UnhandledException? - PullRequest
102 голосов
/ 06 января 2010

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

  • В чем разница между Application.ThreadException и
    AppDomain.CurrentDomain.UnhandledException?

  • Нужно ли обрабатывать оба?

Спасибо!

Ответы [ 4 ]

96 голосов
/ 06 января 2010

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

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

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

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

34 голосов
/ 19 мая 2010

В приложениях, использующих 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 .

18 голосов
/ 06 января 2010

ОК - передо мной, этот фрагмент кода из 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());
}
0 голосов
/ 06 января 2010

Ну, дело в том, что ThreadException происходит из-за проблемы с вашим потоком, Unhandled Exception запускается, если ваш код генерирует исключение, которое не обрабатывается.

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

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

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