简体   繁体   English

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

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

This is getting extremely irritating. 这变得非常恼人。 Right now I have a winforms application, and things were not working right, but no exceptions were being thrown as far as I could tell. 现在我有一个winforms应用程序,但事情没有正常工作,但据我所知,没有例外。 After stepping through almost all pieces of relevant code, it turns out that an exception was being thrown at the start of my application. 在逐步完成几乎所有相关代码之后,事实证明在我的应用程序开始时抛出异常。

Long story short, in WinForms, being as awesome as it is, if an exception occurs the WinForms library ignores it. 简而言之,在WinForms中,如果出现异常,WinForms库会忽略它。 No "an unhandled exception has occurred" JIT message is thrown, it just stops processing the current event and goes back to the GUI. 没有“发生未处理的异常”抛出JIT消息,它只是停止处理当前事件并返回GUI。

This is causing random bugs, because code to load data isn't being called due to the exception occurring prior to this data being loaded. 这会导致随机错误,因为在加载此数据之前发生异常,因此未调用加载数据的代码。

To see this in action I created a brand new WinForms application, and entered the following code: 为了看到这一点,我创建了一个全新的WinForms应用程序,并输入以下代码:

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

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

Press F5 and the form loads without any errors showing, even though a null reference is being thrown. 按F5并加载表单而不显示任何错误,即使正在抛出空引用。

I then tried to go to my Program.cs main method and add Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); 然后我尝试转到我的Program.cs主方法并添加Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); to it. 它。 Still my form loads without causing any errors to be thrown. 仍然我的表单加载而不会导致任何错误被抛出。

Even though I know that I can tell VS to break on all exceptions, I find this situation really bad. 即使我知道我可以告诉VS打破所有异常,我发现这种情况非常糟糕。 It causes really wierd issues that are hard to debug in production, and as this is an internal tool I really want to have it so it actually errors out when an exception occurs, and not silently disregards it. 它导致了很难在生产中调试的奇怪问题,因为这是一个内部工具,我真的很想拥有它,所以当异常发生时它实际上会出错,而不是默默地忽略它。

Does anyone know how to do this? 有谁知道如何做到这一点?


Update: Just to update on things I have learned from the comments. 更新:只是为了更新我从评论中学到的东西。

This does appear to be a 64-bit issue with windows, as I learned from this question which I did not see before posting. 这似乎是一个64位的Windows问题,正如我从这个问题中学到的,我在发布之前没有看到。 In that question it pointed to a Microsoft bug report about this, which had this to say: 在那个问题中,它指出了一个关于此的微软错误报告 ,其中有这样的说法:

Hello, 你好,

This bug was closed as "External" because this behavior results from how x64 version of Windows handle exceptions. 此错误已关闭为“外部”,因为此行为是由x64版本的Windows处理异常引起的。 When a user mode exception crosses a kernel transition, x64 versions of Windows do not allow the exception to propagate. 当用户模式异常穿过内核转换时,x64版本的Windows不允许异常传播。 Therefore attached debuggers are unaware of the fact that an exception occured resulting in the debugger failing to break on the unhandled exception. 因此,附加的调试器不知道发生异常的事实导致调试器未能在未处理的异常上中断。

Unfortunately where is nothing that the Visual Studo team can do to address this, it is the result of operating system design. 不幸的是,Visual Studo团队无法解决这个问题,这是操作系统设计的结果。 All feedback regarding this issue should be addressed to the Windows team; 有关此问题的所有反馈都应提交给Windows团队; however the Windows team considers this to be the "correct" operating system design, and considers the x86 behavior to be "incorrect". 但Windows团队认为这是“正确的”操作系统设计,并认为x86行为“不正确”。

Best Regards, Visual Studio Debugger 最诚挚的问候,Visual Studio Debugger

That being said, builds not run through visual studio (or using Ctrl+F5 to run) does seem to show the JIT exception message box EXCEPT if you have the following code in your Program.cs : 话虽这么说,如果在Program.cs有以下代码,那么构建不通过visual studio(或使用Ctrl + F5运行)似乎确实显示了JIT异常消息框EXCEPT

 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); 

That code will cause windows to ignore the exception. 该代码将导致窗口忽略该异常。

However, if you (instead) subscribe to the Application.ThreadException event, not only will your exceptions be caught, visual studio's debugger will break on unhandled exceptions! 但是,如果您(而不是)订阅Application.ThreadException事件,不仅会捕获您的异常,Visual Studio的调试器在未处理的异常中中断!

In your Program.cs' Main function you should also ensure that you've wrapped your call to open the form in a try/catch. 在Program.cs的主要功能中,您还应确保已打包调用以在try / catch中打开表单。 Additionally use the AppDomain.UnhandledException to catch exceptions. 另外,使用AppDomain.UnhandledException来捕获异常。 We also add Application.ThreadException too. 我们也添加了Application.ThreadException

I believe the following will give you hooks into all the exceptions that can be thrown... 我相信以下内容将为您提供可以抛出的所有异常的钩子...

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);
}

Try the following. 请尝试以下方法。

This is the code snippet: 这是代码片段:

[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);
}

An easy fix is not to run under the debugger. 一个简单的解决方法是不在调试器下运行。

The debugger is masking the exception for some reason. 由于某种原因,调试器正在屏蔽异常。 If you run your app normally (Ctrl+F5), you'll get the usual "Unhandled exception has occurred in your application... Continue/Quit?" 如果您正常运行您的应用程序(Ctrl + F5),您将得到通常的“应用程序中发生未处理的异常...继续/退出?” dialog. 对话。

Having experienced this often and identified the issue regarding 64 bit OS and the Form.Load event, I always just make a point of doing all my start up functions in the Form.Shown event. 经历过这种情况并确定了有关64位操作系统和Form.Load事件的问题后,我总是在Form.Shown事件中完成所有启动功能。 For all practical purposes this is the same thing (aside from a few rare, exceptional circumstances), and the JIT message is produced in the Shown event. 出于所有实际目的,这是相同的事情(除了一些罕见的特殊情况),并且JIT消息在Shown事件中产生。

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

相关问题 是什么原因导致Winforms无声地丢弃未处理的异常(没有尝试/捕获)? - What causes Winforms to silently discard unhandled exceptions (with no try/Catches)? 如何在 WinForms 应用程序中创建一些可以捕获所有“未处理”异常的东西? - How can I make something that catches all 'unhandled' exceptions in a WinForms application? 如何阻止 IConnectableObservable.Wait() 吞下未处理的异常? - How can I stop IConnectableObservable.Wait() from swallowing unhandled exceptions? 无法捕获Winforms中未处理的异常 - Unable to capture Unhandled Exceptions in Winforms 如何正确捕获 WinForms 应用程序中所有未处理的异常 - How to catch all unhandled exceptions in WinForms application correctly 如何捕获另一个进程的未处理异常? - How can I catch the unhandled exceptions of another process? 如何以DRY方式将未处理的程序异常通知管理员? - How can I notify administrators of unhandled program exceptions in a DRY way? 如何在WCF线程中强制未处理的异常使进程崩溃? - How can I force unhandled exceptions in a WCF thread to crash the process? C#Winforms处理未处理的异常 - C# Winforms handle unhandled exceptions 如何停止WinForms应用10分钟? - How can I stop my WinForms app for 10 minutes?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM