Ловля исключения в Основном () метод

Рассмотрите следующее простое заявление: форма окон, созданная "новым приложением Windows C#", упорядочивает в VS, который был изменен следующим способом:

public static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    try
    {
        Application.Run(new Form1());
    }
    catch (Exception ex)
    {
        MessageBox.Show("An unexpected exception was caught.");
    }

}

Form1.cs содержит следующие модификации:

private void Form1_Load(object sender, EventArgs e)
{
    throw new Exception("Error");

}

Если я нажимаю F5 in IDE, то, как я ожидаю, я вижу, что окно сообщения говорит, что исключение было поймано и выходы приложения.

Если я перехожу к Отладке (или Выпуск) / мусорное ведро и запускаю исполняемый файл, я вижу окно "Unhandled exception" стандарта, подразумевая, что мой обработчик исключений не работает.

Очевидно, это имеет некоторое отношение к исключению, бросаемому от другого потока то Приложение. От выполненный называют. Но вопрос остается - почему поведение отличается в зависимости от того, было ли приложение запущено от IDE или из командной строки? Что лучшая практика должна гарантировать, чтобы никакие исключения не оставались необработанными в приложении?

6
задан Corvin 27 April 2010 в 11:27
поделиться

2 ответа

Обычно Application.ThreadException обрабатывает исключение в событии Load. Вы получите ThreadExceptionDialog, который предлагает варианты выхода и продолжения.

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

Вы можете сделать это согласованным, используя Application.SetUnhandledExceptionMode () в методе Main (). Вы не должны, исключения действительно трудно отлаживать, если вы это сделаете. Если вы хотите настроить обработку исключений для потока пользовательского интерфейса, вам следует зарегистрировать собственный обработчик Application.ThreadException:

  if (!System.Diagnostics.Debugger.IsAttached)
    Application.ThreadException += myThreadException;

Для перехвата необработанных исключений в рабочих потоках требуется обработчик AppDomain.UnhandledException. Они не подлежат восстановлению.

Также будьте осторожны с ошибкой в ​​64-битной Windows, исключения в событии Load проглатываются без диагностики при подключении отладчика. Включите режим AnyCPU, чтобы избежать этой ловушки.

10
ответ дан 8 December 2019 в 15:59
поделиться

В дополнение к перехвату любых исключений, возникающих внутри метода Main , вы также должны обрабатывать исключения AppDomain.CurrentDomain.UnhandledException и Application.ThreadException .

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

5
ответ дан 8 December 2019 в 15:59
поделиться