2

Consider the following code snippet in Program.cs:

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        // throw any exceptions inside event handlers
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);

        try
        {
            using(var frm = new Form1())
            {
                Application.Run(frm);
            }
        }
        catch
        {
            MessageBox.Show("Caught exception");
        }
    }

That is: when the form throws an exception, the catch block executes, and the user is alerted that something bad has happened.

This works fine, except when an exception is thrown inside the load event of the form:

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

In this case, the catch block still executes, but the MessageBox won't show (the MessageBox.Show() call immediately returns).

Why is that?

After some trial and error, I found two slight variations, in which the MessageBox does show. One is by leaving out the using block:

        try
        {
            Application.Run(new Form1());
        }
        catch
        {
            MessageBox.Show("Caught exception");
        }

One is by calling ShowDialog instead of Application.Run().

        try
        {
            using(var frm = new Form1())
            {
                frm.ShowDialog();
            }
        }
        catch
        {
            MessageBox.Show("Caught exception");
        }

This is all very strange to me. I stumbled upon this problem because I am writing some generic error handling piece of code (in which I don't know how the user of my code is going to start his application).

Q1: Is there an explanation for this strange behavior?

Q2: Is there something I can do to make the first example work as well?


Edit

Someone linked this question as a potential duplicate. However, I don't think it applies here. The case I'm describing happened on 32bit Windows. Also it does not matter whether or not there is a debugger attached. Finally, the linked question is about Visual Studio not breaking when an exception inside the load event first. Here, Visual Studio breaks just fine, it's about the subsequent MessageBox that won't show.

Community
  • 1
  • 1
Andreas
  • 1,751
  • 2
  • 14
  • 25
  • From what you describe: `using()` will `Dispose()` your `Form1`. If the last window is closed, your Application is shut down. This may explain why the MessageBox is not shown. – DrKoch Jan 24 '15 at 12:51
  • @DrKoch. see the last example. There the form is also disposed, yet the MessageBox shows. – Andreas Jan 24 '15 at 12:54
  • Strange, at runtime there should be no difference between the two cases where `using` is used. – kennyzx Jan 24 '15 at 12:59
  • Just wondering, why use Application.Run to show a form? – NoChance Jan 24 '15 at 13:11
  • 1
    @EmmadKareem: it's the default in a WinForms project (just create an empty project and look at program.cs). Btw. this is just an example, in a realistic project, Form1 would be the main form of the application, and any subsequent forms would be shown with .Show() or .ShowDialog(). – Andreas Jan 24 '15 at 13:27
  • Correct, I never used it to show forms explicitly from code. – NoChance Jan 24 '15 at 13:34

0 Answers0