tags:

views:

153

answers:

4

I have a test winforms app with ThreadExceptionHandler that displays a message box when an unhandled exception is caught, as follows:

[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");
}

When I force an error in the ctor of Form 1 (e.g. dividebyzero) as follows:

public Form1()
{
     InitializeComponent();

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

and run the app outside of Visual Studio (in Windows 7), the divide by zero exception is not handled - I get an unhelpful "WindowsFormApplication1 has stopped working..." message.

However, when I move the dividebyzero exception to the Form1_Load event and rerun, the exception is handled properly.

Can someone explain why this is the case? The reason I ran this test program is because I am experiencing a similar unhandled exception issue in another, enterprise app that I am trying to track down.

+2  A: 

The error is being thrown in the constructor, not in the threaded code. Your code:

Application.Run(new Form1());

is going to throw the exception right then and there, on that very line of code, before the call to Application.Run(), so the threaded code doesn't even begin executing.

Shaul
+3  A: 

This is probably due to the fact that the constructor is executed before Application.Run() is called. Your code could also be written as

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

Your thread exception handler only becomes active when Application.Run() is executing. In order to catch exceptions in the form constructor, you need to surround Form1 MyForm = new Form1(); witch a seperate try/catch block.

Treb
+1 - Your clear description beats mine... :)
Shaul
+1  A: 

ThreadException handles exceptions UI thread exceptions. UnhandledException handles non-UI thread exceptions.

You need to add this line to your Main():

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

and the following to your class:

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    MessageBox.Show("error caught 2");
}
serialhobbyist
A: 

Application.ThreadException event is called every time Application throws an exception, however in your example, the exception is thrown in the main thread, you can add a try catch block for it.

Clangon