Winforms应用程序中的未处理异常

8
我有一个简单的WinForms应用程序,用于输入测试用例。自从我将这个应用程序升级到.NET 4.0并添加了一个新的选项卡页面来验证XML与XSD模式,该应用程序就会随机崩溃。我无法重现异常。
我的QA人员收到的错误是通用的Windows消息:
TestCaseViewer遇到问题需要关闭。我们为此表示抱歉。
为了尝试找到真正的错误,我已经在程序的Main方法开头添加了以下代码:
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        Application.ThreadException += Application_ThreadException;

事件处理程序的格式如下所示:
    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        try
        {
            MessageBox.Show(e.Exception.ToString(), @"Thread Exception", 
                MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }
        finally 
        {
            Application.Exit();    
        }
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        try
        {
            var ex = (Exception)e.ExceptionObject;
            MessageBox.Show(ex.ToString(), @"Unhandled Exception",
                MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }
        finally 
        {
            Application.Exit();    
        }
    }

不幸的是,这并没有起到帮助作用,无论是什么导致错误的东西都会以一种生成未处理错误并冒泡到操作系统的方式继续发生。

有人能给我关于捕获此异常的其他想法吗?


堆栈跟踪?MessageBox.Show(e.Stacktrace); - anon271334
只要堆栈跟踪不为空,当异常调用ToString()时,它将被返回。 - Loathian
2个回答

11
尝试将以下内容添加到您的app.config文件中。
<runtime>
   <!-- the following setting prevents the host from closing when an unhandled exception is thrown -->
   <legacyUnhandledExceptionPolicy enabled="1" />
</runtime>

10
我不太清楚这个是做什么用的,但是它看起来非常可疑。你需要修复该问题,而不是为了让你的程序在未知状态下盲目运行而自我陶醉。 - Evan Harper

2
如果您使用的是Visual Studio,则可以将其设置为在所有未处理的异常发生时中断,甚至在抛出异常时中断,无论代码是否处理该异常。
要做到这一点,请从“调试”菜单中选择“异常”。您会得到一个对话框,看起来像这样:
如果您真的想认真对待问题,请尝试勾选所有复选框。然后,从QA人员那里找出触发异常的确切操作,并在开发环境下在调试器下精确地重现这些操作。每当抛出异常时,Visual Studio都会中断,您将看到有问题的代码行以及完整的堆栈跟踪。

我实际上已经在我的IDE中勾选了那个设置。问题是,我无法重现他只是在数据网格中随意点击时出现的错误。错误不会以相同的方式连续两次显现。我有一种感觉,这可能是数据绑定线路或处理网格位置更改的代码中存在问题。 - Loathian
@Loathian:这个测试员在你们公司吗?把他带到你的电脑旁边,让他重现这个bug。我不确定你在这里还在寻找什么其他类型的答案。如果你无法重现一个bug,那么几乎不可能修复它。每个bug数据库都有一个“无法重现”的选项,出于这个原因。如果这是一个远程位置的客户有特殊需求,情况可能会有所不同,但是如果你自己的QA部门无法帮助你重现它,我怀疑这里没有人能够帮助你。 - Cody Gray
他是我们公司的一名测试员,实际上就坐在我对面。如果他能再次重现错误,我会让他使用一些调试工具来捕获它,看看是否可以通过这种方式获取堆栈跟踪。我只是想找个人来审查我的异常处理代码,看看我是否犯了任何错误。 - Loathian
今天我们追踪到了...错误是由我们用于以“漂亮”的格式呈现XML的WinForms控件引发的。看起来当在控件上调用dispose时,错误被抛出。该控件是:System.Windows.Forms.WebBrowser ... 这里是错误信息:System.Windows.Forms.UnsafeNativeMethods+IOleObject.SetClientSite(IOleClientSite) at System.Windows.Forms.WebBrowserBase.TransitionFromRunningToLoaded() at System.Windows.Forms.WebBrowserBase.TransitionDownTo(AXState) at System.Windows.Forms.WebBrowser.Dispose(Boolean) - Loathian
@Loathian:我认为我说过一个正确设计的应用程序不应该调用“Application.Exit”。这个语句背后的原因是,当您关闭打开的所有窗体时,您的应用程序将自动关闭。调用“Application.Exit”本身并没有什么本质上的问题,但是如果必须这样做才能让应用程序退出,则表明您管理资源出现了问题,并且没有跟踪您创建/显示的窗体对象。在您的“finally”块中使用它是完全合理的,因为您显式地防范可能抛出的异常。 - Cody Gray
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接