繁体   English   中英

如何让WinForms静静地忽略未处理的异常?

[英]How can I get WinForms to stop silently ignoring unhandled exceptions?

这变得非常恼人。 现在我有一个winforms应用程序,但事情没有正常工作,但据我所知,没有例外。 在逐步完成几乎所有相关代码之后,事实证明在我的应用程序开始时抛出异常。

简而言之,在WinForms中,如果出现异常,WinForms库会忽略它。 没有“发生未处理的异常”抛出JIT消息,它只是停止处理当前事件并返回GUI。

这会导致随机错误,因为在加载此数据之前发生异常,因此未调用加载数据的代码。

为了看到这一点,我创建了一个全新的WinForms应用程序,并输入以下代码:

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

    private void Form1_Load(object sender, EventArgs e)
    {
        string blah = null;
        blah.Trim();
    }
}

按F5并加载表单而不显示任何错误,即使正在抛出空引用。

然后我尝试转到我的Program.cs主方法并添加Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); 它。 仍然我的表单加载而不会导致任何错误被抛出。

即使我知道我可以告诉VS打破所有异常,我发现这种情况非常糟糕。 它导致了很难在生产中调试的奇怪问题,因为这是一个内部工具,我真的很想拥有它,所以当异常发生时它实际上会出错,而不是默默地忽略它。

有谁知道如何做到这一点?


更新:只是为了更新我从评论中学到的东西。

这似乎是一个64位的Windows问题,正如我从这个问题中学到的,我在发布之前没有看到。 在那个问题中,它指出了一个关于此的微软错误报告 ,其中有这样的说法:

你好,

此错误已关闭为“外部”,因为此行为是由x64版本的Windows处理异常引起的。 当用户模式异常穿过内核转换时,x64版本的Windows不允许异常传播。 因此,附加的调试器不知道发生异常的事实导致调试器未能在未处理的异常上中断。

不幸的是,Visual Studo团队无法解决这个问题,这是操作系统设计的结果。 有关此问题的所有反馈都应提交给Windows团队; 但Windows团队认为这是“正确的”操作系统设计,并认为x86行为“不正确”。

最诚挚的问候,Visual Studio Debugger

话虽这么说,如果在Program.cs有以下代码,那么构建不通过visual studio(或使用Ctrl + F5运行)似乎确实显示了JIT异常消息框EXCEPT

 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); 

该代码将导致窗口忽略该异常。

但是,如果您(而不是)订阅Application.ThreadException事件,不仅会捕获您的异常,Visual Studio的调试器在未处理的异常中中断!

在Program.cs的主要功能中,您还应确保已打包调用以在try / catch中打开表单。 另外,使用AppDomain.UnhandledException来捕获异常。 我们也添加了Application.ThreadException

我相信以下内容将为您提供可以抛出的所有异常的钩子...

static void Main()
{
    try
    {
        System.Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        System.Windows.Forms.Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(OnGuiUnhandedException);
        AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;

        var form = new MainForm();
        form.ShowDialog();
    }
    catch (Exception e)
    {
        HandleUnhandledException(e);
    }
    finally
    {
        // Do stuff
    }
}

private static void HandleUnhandledException(Object o)
{
    // TODO: Log it!
    Exception e = o as Exception;

    if (e != null)
    {

    }
}

private static void OnUnhandledException(Object sender, UnhandledExceptionEventArgs e)
{
    HandleUnhandledException(e.ExceptionObject);
}

private static void OnGuiUnhandedException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
    HandleUnhandledException(e.Exception);
}

请尝试以下方法。

这是代码片段:

[STAThread]
public static void Main(string[] args)
{
    try
    {
        Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
        //your program entry point
    }
    catch (Exception ex)
    {
       //manage also these exceptions
    }
}

private void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
    ProcessException(e.Exception);
}

一个简单的解决方法是不在调试器下运行。

由于某种原因,调试器正在屏蔽异常。 如果您正常运行您的应用程序(Ctrl + F5),您将得到通常的“应用程序中发生未处理的异常...继续/退出?” 对话。

经历过这种情况并确定了有关64位操作系统和Form.Load事件的问题后,我总是在Form.Shown事件中完成所有启动功能。 出于所有实际目的,这是相同的事情(除了一些罕见的特殊情况),并且JIT消息在Shown事件中产生。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM