Проглотить исключение в приложении WinForm С#

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

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


person Rahul Vasantrao Kamble    schedule 22.04.2020    source источник
comment
Это распространяет исключение на моей машине и в .net 4.7.2. Какую версию ты используешь?   -  person Oguz Ozgul    schedule 22.04.2020
comment
Удалите этот блок try/catch вокруг Application.Run(new Form1());   -  person Jimi    schedule 22.04.2020
comment
stackoverflow.com/a/14858978/17034   -  person Hans Passant    schedule 22.04.2020


Ответы (2)


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

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

Когда вы запускаете свою программу с Application.Run(), она запускает цикл сообщений и создает ThreadContext и ApplicationContext.

Цикл сообщений обрабатывает оконные сообщения, отправленные в активную форму (скажем, нажатие клавиши Tab на числовом элементе управления) и выполняет необходимые действия.

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

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.

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

person Oguz Ozgul    schedule 22.04.2020
comment
Form1_Leave обрабатывает событие выхода из текстового поля и работает нормально, отправляя исключение в блок catch. Идея уловки вокруг Application.Run состоит в том, чтобы показать мою собственную форму, которая объясняет исключение на моем языке. Мне до сих пор не ясно, чем событие изменения значения отличается от события выхода из текстового поля. - person Rahul Vasantrao Kamble; 22.04.2020
comment
Да не должно быть, так как я прямо подтверждал такое поведение из исходников. Я посмотрю на это дальше. - person Oguz Ozgul; 22.04.2020

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

 try
        {
            Application.Run(new Form1());
        }
        catch (Exception)
        {
            MessageBox.Show("Exception Hadled");
        }
person Aamer Khawaja    schedule 22.04.2020
comment
Это не имеет никакого значения... особенно если вы даже не присваиваете ему переменную. Это полностью идентично отключению части (Exception). - person Nyerguds; 22.04.2020