【问题标题】:Exception handling behavior in WinForms application, which uses modal dialogWinForms 应用程序中的异常处理行为,它使用模态对话框
【发布时间】:2012-04-28 13:53:18
【问题描述】:

我遇到过这样的情况。 WinForms 应用程序有两种形式。主窗体有一个按钮,当用户单击它时,会显示模态对话框。对话框表单也有一个按钮,当用户点击它时,会抛出异常。

异常处理不同,当应用程序在调试器下运行并自行运行时。 这是重现此行为的最少代码:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            using (var dialog = new Form2())
            {
                dialog.ShowDialog();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Oops! " + ex.Message);
        }
    }
}

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        throw new NotImplementedException();
    }
}

调试时,引发异常会关闭对话框,Form1.button1_Click 中的异常处理程序会处理异常。

运行应用程序本身时,引发异常不会关闭对话框。取而代之的是调用默认的 Application.ThreadException 处理程序。

为什么(以及为什么)行为会有所不同?怎样才能使它们相互协调?

【问题讨论】:

    标签: c# winforms exception-handling


    【解决方案1】:

    在你的 Program.Main() 中试试这个:

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
        Application.Run(new Form1());
    }
    

    原因与 Windows 窗体程序集在 Visual Studio 托管进程之外运行的方式有关。 看到这个:

    http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx

    如果将上面的代码行设置为:

    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    

    并在 VS 中运行它,您将看到默认行为是什么 - 一旦您跳过代码中的初始异常,就会显示您所引用的对话框。默认值只是不同,具体取决于您是在托管模式下运行还是在独立模式下运行。

    嗯,“为什么”在 MS 链接中有所涉及 - 错误发生在事件处理程序中,该处理程序位于不同的线程上。默认行为是区别对待,仅在 WinForms 下。如果您在调用对话框之后添加此行:

    throw new Exception("Bah!");
    

    并保持 CatchException 上的行为,您将看到它如您所期望的那样进入您的异常处理程序。只有事件处理程序中的异常处理方式不同。希望对您有所帮助。

    【讨论】:

    • 谢谢!这是我问题的“如何”部分的答案。 “为什么和为什么”仍然是真实的......
    • 明白了;为什么/为什么我会归结为这只是 .NET 框架的怪癖之一。我可能会得到纠正,我很想知道是否有人知道为什么这种行为会因应用程序运行的上下文而有所不同的充分理由。我同意这有点问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 2020-06-28
    • 1970-01-01
    • 2018-04-01
    相关资源
    最近更新 更多