Исключительная ласточка в приложении WinForm c# - PullRequest
2 голосов
/ 22 апреля 2020
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);
        }
    }

И в Program.cs имеется блок catch, как следует

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

В приведенном выше примере окно сообщения не вызывается. Но если я использую отпуск, событие catch выполняется. Почему событие ValueChanged не является исключением Prapogating для внешнего мира?

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Это не так, и это по замыслу. Не пытайтесь / ловите вокруг Application.Run ().

ваш обработчик событий Form_Leave также должен иметь такое же поведение.

Когда вы запускаете вашу программу с Application.Run(), она запускает l oop и создает ThreadContext и ApplicationContext.

Сообщение l oop обрабатывает оконные сообщения, отправляемые в активную форму (скажем, нажатие клавиши Tab при управлении цифрой c) и выполняет необходимые действия.

Это то, что обрабатывает исключение при первом получении:

internal void UpdateFocusedControl() in ContainerControl:

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

Теперь OnThreadException вызывает ваш Application_ThreadException.

Давайте попробуем бросить снова здесь.

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

В следующий раз исключение обрабатывается 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);
}

И, наконец, когда вы перебрасываете, на этот раз ваш оператор catch активируется.

Надеюсь, это прояснит ситуацию на вашей стороне.

0 голосов
/ 22 апреля 2020

Измените свой код на это:

 try
        {
            Application.Run(new Form1());
        }
        catch (Exception)
        {
            MessageBox.Show("Exception Hadled");
        }
...