2
public partial class Form1 : Form
    {
        public class abc
        {
            public static decimal Divide(int a,int b)
            {
                return a / b;
            }
        }
        public Form1()
        {
            InitializeComponent();
            numericUpDown1.ValueChanged += NumericUpDown1_ValueChanged;
            numericUpDown1.Controls[1].Leave += Form1_Leave;
        }

        private void Form1_Leave(object sender, EventArgs e)
        {
            //abc.Divide(15, 0);
        }

        private void NumericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            abc.Divide(15, 0);
        }
    }

And Program.cs is haveing catch block as follow

static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.ThreadException += Application_ThreadException;
            try
            {
                Application.Run(new Form1());
            }
            catch
            {
                MessageBox.Show("Exception Hadled");
            }
        }

        private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            MessageBox.Show("Exception Hadnled");
        }
    }

In Above sample, no message box is triggered. But if I use leave event catch executes. Why ValueChanged event is not Prapogating exception to outer world?

2 Answers2

1

It is not, and this is by design. Don't have try/catch around Application.Run().

your Form_Leave event handler should also has the same behavior.

When you start your program with Application.Run(), it starts a message loop and creates a ThreadContext and ApplicationContext.

The message loop handles window messages sent to the active form (let's say the Tab key-press when on the numeric control) and executes required actions.

This is what handles the exception when you first get it:

internal void UpdateFocusedControl() in ContainerControl:

try {
    leaveControl.NotifyLeave();
}
catch (Exception e) {
    Application.OnThreadException(e);
}

Now OnThreadException calls your Application_ThreadException.

Let's try to throw again here.

private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
    MessageBox.Show("Exception Handled");
    throw e.Exception;
}

Next time, the exception is handled by the ThreadContext

internal bool PreTranslateMessage(ref NativeMethods.MSG msg) in Application+ThreadContext

try
{
    // Message processing, like leave control and focus next and call event handlers
}
catch (Exception e)
{
    OnThreadException(e);
}

And finally, when you re-throw, this time your catch statement is activated.

Hope this clarifies things on your side.

Oguz Ozgul
  • 6,809
  • 1
  • 14
  • 26
  • Form1_Leave is handling texts box leave event and its working fine by sending exception to catch block. The idea behind having catch around Application.Run is to show my own form which explains exception in my language. I am still not clear how value changed event is different than texts box leave event. – Rahul Vasantrao Kamble Apr 22 '20 at 14:39
  • Yes, it should not be, as I directly confirmed this behavior from the source code. I will look into it further. – Oguz Ozgul Apr 22 '20 at 14:57
0

Change your code to this:

 try
        {
            Application.Run(new Form1());
        }
        catch (Exception)
        {
            MessageBox.Show("Exception Hadled");
        }
Aamer Khawaja
  • 17
  • 1
  • 6
  • That makes no difference whatsoever... especially if you're not even assigning a variable to it. It's completely identical to leaving the `(Exception)` part off. – Nyerguds Apr 22 '20 at 13:40