ThreadExceptionHandler не перехватывает исключение в конструкторе MainFrm - PullRequest
1 голос
/ 14 июля 2009

У меня есть тестовое приложение winforms с ThreadExceptionHandler, которое отображает окно сообщения при обнаружении необработанного исключения следующим образом:

[STAThread]
static void Main()
{
    Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
    MessageBox.Show("error caught");
}

Когда я навязываю ошибку в ctor формы 1 (например, divbyzero) следующим образом:

public Form1()
{
     InitializeComponent();

     int i = 0;
     int x = 5 / i;
}

и запустите приложение вне Visual Studio (в Windows 7), исключение деления на ноль: не обработано - я получаю бесполезное сообщение «WindowsFormApplication1 прекратил работать ...».

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

Может кто-нибудь объяснить, почему это так? Причина, по которой я запустил эту тестовую программу, заключается в том, что у меня возникла похожая проблема с необработанными исключениями в другом корпоративном приложении, которое я пытаюсь отследить.

Ответы [ 4 ]

4 голосов
/ 14 июля 2009

Вероятно, это связано с тем, что конструктор выполняется до вызова Application.Run(). Ваш код также может быть записан как

[STAThread]
static void Main()
{
    Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Form1 MyForm = new Form1();
    Application.Run(MyForm);
}

Ваш обработчик исключений потока становится активным, только когда выполняется Application.Run(). Чтобы перехватывать исключения в конструкторе формы, вам необходимо окружить Form1 MyForm = new Form1(); отдельным блоком try / catch.

3 голосов
/ 14 июля 2009

Ошибка генерируется в конструкторе , а не в многопоточном коде. Ваш код:

Application.Run(new Form1());

сразу же вызовет исключение в той же строке кода перед вызовом Application.Run(), поэтому многопоточный код даже не начнет выполняться.

1 голос
/ 14 июля 2009

ThreadException обрабатывает исключения исключений потока пользовательского интерфейса. UnhandledException обрабатывает исключения потока не-пользовательского интерфейса.

Вам необходимо добавить эту строку в свой Main ():

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

и следующее для вашего класса:

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    MessageBox.Show("error caught 2");
}
0 голосов
/ 14 июля 2009

Событие Application.ThreadException вызывается каждый раз, когда приложение генерирует исключение, однако в вашем примере исключение выдается в основном потоке, для него можно добавить блок try catch.

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