我想了解我的应用崩溃时Windows事件日志的工作方式,因此我向throw new Exception()
添加了一个测试按钮。令我惊讶的是,该应用程序一直在运行。 Windows将显示一个对话框,其中包含“继续”或“退出”选项,然后单击“继续”,该应用程序将继续运行。我希望该应用程序在发生未处理的异常后继续运行后会崩溃。
有关此主题的大多数博客都使用小型除以零的控制台应用程序进行测试,但是我认为创建小型Forms应用程序并不会增加太多麻烦。在现实世界中,我需要了解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按钮的频率如何,该应用程序都不会停止或退出。通过单击“更新”按钮,时间显示将更新,就好像没有发生异常一样。
未处理的异常唯一要做的就是该按钮的时间更新不起作用。
这怎么可能?
顺便说一句,我的问题不是关于difference between Application.ThreadException and AppDomain.CurrentDomain.UnhandledException。实际上,我从未听说过这些例外情况。我的问题也不是必须同时处理这两个异常。我的问题和另一个问题似乎都提到了相同的Application.SetUnhandledExceptionMode()方法。这肯定是一个有趣的方法。我认为,我的问题不是重复的。但是,与其他问题的链接可能有助于更深入地了解WinForm幕后发生的事情。
答案 0 :(得分:3)
阅读了steve16351的注释建议的ms doc on the link之后,我了解到Windows Forms应用程序具有默认的异常处理程序。
通过在使用以下方法在Program.cs中创建表单之前禁用该处理程序:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
未处理的异常将导致不同的Windows对话框,并带有
选项因此现在无法继续使用“更新”按钮。
PS:很抱歉看到他在我要对其进行投票之前删除了他的评论
更新:
这个问题听起来多么愚蠢,事实证明,如果您打算使用Program.cs中的try-catch块捕获WinForms应用程序的所有异常,则此设置至关重要。如果没有此设置,则仅当在VS调试器中运行时,窗体中的异常才会被捕获在此类块中,而不是通过双击资源管理器窗口中的* .exe来捕获。
如果未在Form中捕获异常,则显然将Form中引发的异常视为未处理。您可以尝试在创建窗体的Program.cs中捕获它,但是默认的应用程序处理程序可能会首先捕获它。奇怪但真实:-)