Исключение во время выполнения ловится по-разному внутри и снаружи MSVS - PullRequest
5 голосов
/ 29 сентября 2011

Я вызываю следующую функцию, где-то в программе, которая выдаст исключение

public static List<Templates> LoadTemplates()
{
    // ...
    // System.Threading.Thread.CurrentThread.ManagedThreadId == 1 // ID written to log file
    System.IO.Directory.GetFiles("does_not_exist_directory");
    // ...
}

И я пытаюсь отловить исключение в программе по умолчанию .cs

try
{
    // System.Threading.Thread.CurrentThread.ManagedThreadId == 1
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}
catch (Exception ex)
{
    MessageBox.Show("ERROR CAUGHT");
}
finally { // do clean up }

При запуске в MSVS исключение получается, как и ожидалось. Но при запуске двойным щелчком по файлу .exe в выходной директории в диалоговом окне с сообщением появляется сообщение об исключении

EDIT:

Чтобы перехватить ошибку при запуске .exe из выходного каталога, код должен быть скомпилирован с обработкой события Application.ThreadException

Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(new Form());

Но тогда MSVS будет вести себя нежелательно, показывая собственный диалог MSVS «Советы по устранению неполадок» без полей «Unhandled Exception».

Как я могу гарантировать, что он ведет себя одинаково как в MSVS, так и вне ее?

Ответы [ 3 ]

4 голосов
/ 29 сентября 2011

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

Вы можете подписаться на несколько событий, чтобы поймать все из них:

пожалуйста, прочитайте / обратите внимание на документы (первое должно быть сделано) - есть некоторые предостережения.

0 голосов
/ 02 октября 2011

Относительно поведения исключений в и из MSVS, Карстен был прав, указав мне на код в MSDN, но Woni помог мне лучше понять ситуацию.

(могло бы быть иначе, но)Похоже, что MSVS подключает свой внутренний обработчик событий к приложению, когда он запускается изнутри MSVS, и этот обработчик запускается перед моим обработчиком в приложении.Следовательно, когда возникает необработанное исключение, MSVS покажет свое собственное диалоговое окно «Советы по устранению неполадок», указывающее на строку ошибки.

В этот момент, если я нажимаю продолжить (F5), чтобы продолжить выполнение кода, MSVS перезапустит-бросьте исключение, и на этот раз оно будет перехвачено моими собственными обработчиками.

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

0 голосов
/ 29 сентября 2011

Похоже, ваш вызов LoadTemplates выполнен в собственном потоке.Я предполагаю, что вы не видите MessageBox в режиме отладки.Вы увидите окно исключений Visual Studio.

Чтобы решить эту проблему, попробуйте использовать событие AppDomain.CurrentDomain.UnhandledException:

[STAThread]
static void Main() {
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
    MessageBox.Show("Unhandled exception");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...