首页 > 解决方案 > 为什么我的应用程序在出现未处理的异常后不会停止?

问题描述

我想了解当我的应用程序崩溃时 Windows 事件日志是如何工作的,所以我在throw new Exception(). 令我惊讶的是,该应用程序一直在运行。Windows 显示一个对话框,其中包含继续或退出选项,然后单击继续,应用程序将继续运行。我预计应用程序会在出现未处理的异常后继续崩溃。

大多数关于这个主题的博客都使用一个除以零的小型控制台应用程序进行测试,但我认为创建一个小型 Forms 应用程序并不会增加太多麻烦。在现实世界中,我需要知道我的表单应用程序的行为方式。这是带有两个按钮的代码:一个用于更新时间显示,以证明应用程序确实在运行,另一个用于引发未处理的异常。

using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            label_Msg.Text = DateTime.Now.ToString();
        }

        private void button_CrashNow_Click(object sender, EventArgs e)
        {
            throw new DivideByZeroException("This is Sandbox Crash Test");
            label_Msg.Text = DateTime.Now.ToString();
        }

        private void button_UpdateTime_Click(object sender, EventArgs e)
        {
            label_Msg.Text = DateTime.Now.ToString();
        }
    }
}

使用 F5 在 VS2017 调试器中运行它将在异常处停止。继续按 F5 将结束应用程序。

但是从 bin/debug 文件夹运行它,通过双击 .exe 文件,应用程序不会停止或退出,无论我多久点击一次 CrashNow 按钮。通过单击更新按钮,时间显示会更新,就好像没有发生异常一样。

未处理异常的唯一作用是该按钮的时间更新不起作用。

这怎么可能?


顺便说一句,我的问题不是关于Application.ThreadException 和 AppDomain.CurrentDomain.UnhandledException 之间的区别。事实上,我从未听说过这些例外。我的问题也不是关于必须处理这两个例外。我的问题和其他问题似乎提到了相同的 Application.SetUnhandledExceptionMode() 方法。这无疑是一种有趣的方法。在我看来,我的问题并不重复。但是,指向其他问题的链接可能有助于更深入地了解 WinForm 引擎盖下发生的事情。

标签: c#.netwinformsexception

解决方案


在阅读了steve16351 评论建议的链接上的 ms 文档后,我了解到 Windows 窗体应用程序有一个默认的异常处理程序。

通过在 Program.cs 中创建表单之前禁用该处理程序,使用:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);

未处理的异常将导致一个不同的窗口对话框,选项

  • 在线检查解决方案并关闭程序
  • 关闭程序
  • 调试程序

所以现在无法继续使用更新按钮。

PS:我很遗憾看到他在我想投票之前删除了他的评论


更新:

这个问题听起来多么愚蠢,事实证明,如果您正在考虑使用 Program.cs 中的 try-catch 块捕获 WinForms 应用程序的所有异常,则此设置是必不可少的。如果没有此设置,只有在 VS 调试器中运行时才会在此类块中捕获表单中的异常,而不是在资源管理器窗口中双击 *.exe。

如果在 Form 中没有捕获到 Form 中抛出的异常,则该异常显然被认为是未处理的。您可以尝试在创建表单的 Program.cs 中捕获它,但默认应用程序处理程序可能会首先捕获它。奇怪但真实:-)


推荐阅读