Why does an exception throw the "ShowDialog" behavior to others if it is running with a Visual Studio debugger application?

Consider this: Form1 launches Form2 as a modal dialog with a call to "System.Windows.Forms.Form.ShowDialog". Form2 throws an exception in the GUI thread.

If I run this program from the Visual Studio debugger, I can catch this exception on the call site in Form1 (which I did not expect!). If I did not run the program without an attached debugger, even if I attach the debugger later, I cannot catch an Exception from Form1 (this is more like behavior).

Why can I catch an exception in Form1 when working in the debugger? Or, more importantly, why does the presence of the debugger change the behavior of the exception from "ShowDialog" "

The following code is enough to demonstrate the problem.

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

    public class Form1 : Form
    {
        public Form1()
        {
            this.MouseClick += this.OnMouseClick;
        }

        private void OnMouseClick(object sender, MouseEventArgs e)
        {
            try
            {
                var f2 = new Form2();
                f2.ShowDialog(this);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(this, ex.Message, "Exception Caught!",
                    MessageBoxButtons.OK, MessageBoxIcon.Information
                    );
            }
        }
    }

    public class Form2 : Form
    {
        public Form2()
        {
            this.MouseClick += this.OnMouseClick;
        }

        private void OnMouseClick(object sender, MouseEventArgs e)
        {
            throw new Exception("Hey! That hurts!");
        }
    }
}
+4
source share
2 answers

This is done to help you debug unhandled exceptions. ShowDialog () is special, this method does not return until you close the dialog. It becomes as modal as when you start another dispatcher loop, the exact equivalent of Application.Run ().

, , ( ), Application.UnhandledException. , . , , . . , , , .

, catch . , .

, Main(), UnhandledExceptionMode.ThrowException Application.SetUnhandledExceptionMode(). , , , . , , . AppDomain.CurrentDomain.UnhandledException, , , . :

    [STAThread]
    static void Main() {
        if (!System.Diagnostics.Debugger.IsAttached) {
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        }
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
        MessageBox.Show(e.ExceptionObject.ToString());
        // Workaround for Windows 10.0.10586 bug:
        AppDomain.CurrentDomain.UnhandledException -= CurrentDomain_UnhandledException;
        Environment.Exit(1);
    }

catch . , catch-em-all. . , , , . , . Debug > Windows > Exception Settings > " ", .

+6

Source: https://habr.com/ru/post/1654424/


All Articles