VS2010 在 64 位版本的 Windows 上的 WinForms 应用程序中不显示未处理的异常消息 [英] VS2010 does not show unhandled exception message in a WinForms Application on a 64-bit version of Windows

查看:24
本文介绍了VS2010 在 64 位版本的 Windows 上的 WinForms 应用程序中不显示未处理的异常消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我创建一个新项目时,对于未处理的异常,我得到了一个奇怪的行为.这是我重现问题的方法:

When I create a new project, I get a strange behavior for unhandled exceptions. This is how I can reproduce the problem:

1) 创建一个新的 Windows 窗体应用程序(C#、.NET Framework 4、VS2010)

1) create a new Windows Forms Application (C#, .NET Framework 4, VS2010)

2) 将以下代码添加到 Form1_Load 处理程序:

2) add the following code to the Form1_Load handler:

int vara = 5, varb = 0;
int varc = vara / varb;
int vard = 7;

我希望 VS 中断并在第二行显示一条未处理的异常消息.然而,结果是第三行被跳过了,没有任何消息,应用程序继续运行.

I would expect that VS breaks and shows an unhandled exception message at the second line. However, what happens is that the third line is just skipped without any message and the application keeps running.

我现有的 C# 项目没有这个问题.所以我猜我的新项目是用一些奇怪的默认设置创建的.

I don't have this problem with my existing C# projects. So I guess that my new projects are created with some strange default settings.

有人知道我的项目有什么问题吗???

Does anyone have an idea what's wrong with my project???

我尝试选中调试->异常中的框.但是即使我在 try-catch 块中处理异常,执行也会中断;这也不是我想要的.如果我没记错的话,此对话框中有一个名为未处理的异常"或类似内容的列,它完全符合我的要求.但是在我的项目中只有一列(Thrown").

I tried checking the boxes in Debug->Exceptions. But then executions breaks even if I handle the exception in a try-catch block; which is also not what I want. If I remember correctly, there was a column called "unhandled exceptions" or something like this in this dialog box, which would do excatly what I want. But in my projects there is only one column ("Thrown").

推荐答案

这是一个由 wow64 仿真层引起的令人讨厌的问题,该层允许 32 位代码在 64 位版本的 Windows 7 上运行.它吞下异常响应 64 位窗口管理器生成的通知而运行的代码,例如 Load 事件.阻止调试器看到它​​并介入.这个问题很难解决,微软的 Windows 和 DevDiv 组正在来回指责.DevDiv 对此无能为力,Windows 认为这是正确且记录在案的行为,听起来很神秘.

This is a nasty problem induced by the wow64 emulation layer that allows 32-bit code to run on the 64-bit version of Windows 7. It swallows exceptions in the code that runs in response to a notification generated by the 64-bit window manager, like the Load event. Preventing the debugger from seeing it and stepping in. This problem is hard to fix, the Windows and DevDiv groups at Microsoft are pointing fingers back and forth. DevDiv can't do anything about it, Windows thinks it is the correct and documented behavior, mysterious as that sounds.

它肯定是记录在案 但几乎没有人理解后果或认为这是合理的行为.尤其是当窗口过程从视图中隐藏时尤其如此,就像在任何使用包装类隐藏窗口管道的项目中一样.像任何 Winforms、WPF 或 MFC 应用程序一样.根本问题是 Microsoft 无法弄清楚如何将异常从 32 位代码流回触发通知的 64 位代码返回到尝试处理或调试异常的 32 位代码.

It is certainly documented but just about nobody understands the consequences or thinks it is reasonable behavior. Especially not when the window procedure is hidden from view of course, like it is in any project that uses wrapper classes to hide the window plumbing. Like any Winforms, WPF or MFC app. Underlying issue is Microsoft could not figure out how to flow exceptions from 32-bit code back to the 64-bit code that triggered the notification back to 32-bit code that tries to handle or debug the exception.

这只是附加调试器的问题,如果没有调试器,您的代码会像往常一样爆炸.

It is only a problem with a debugger attached, your code will bomb as usual without one.

Project > Properties > Build 选项卡 > Platform target = AnyCPU 并取消勾选 Prefer 32-bit.您的应用程序现在将作为 64 位进程运行,从而消除了 wow64 故障模式.一些后果是,它会禁用 VS2013 之前的 VS 版本的编辑 + 继续",并且当您依赖 32 位代码时可能并不总是可行.

Project > Properties > Build tab > Platform target = AnyCPU and untick Prefer 32-bit. Your app will now run as a 64-bit process, eliminating the wow64 failure mode. Some consequences, it disables Edit + Continue for VS versions prior to VS2013 and might not always be possible when you have a dependency on 32-bit code.

其他可能的解决方法:

  • 调试 > 异常 > 勾选 CLR 异常的抛出框以强制调试器在引发异常的代码行处停止.
  • Load 事件处理程序中编写 try/catch 并在 catch 块中编写 failfast.
  • Main() 方法中使用 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException),以便在调试模式下不会禁用消息循环中的异常陷阱.然而,这使得所有未处理的异常难以调试,ThreadException 事件非常无用.
  • 考虑您的代码是否真的属于 Load 事件处理程序.很少需要它,但它在 VB.NET 和绝唱中非常流行,因为它是默认事件,双击简单地添加了事件处理程序.只有当您对应用用户首选项和自动缩放后的实际窗口大小感兴趣时,您才真正需要 Load.其他一切都属于构造函数.
  • 更新到 Windows 8 或更高版本,他们解决了这个 wow64 问题.
  • Debug > Exceptions > tick the Thrown box for CLR exceptions to force the debugger to stop at the line of code that throws the exception.
  • Write try/catch in the Load event handler and failfast in the catch block.
  • Use Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException) in the Main() method so that the exception trap in the message loop isn't disabled in debug mode. This however makes all unhandled exceptions hard to debug, the ThreadException event is pretty useless.
  • Consider if your code really belongs in the Load event handler. It is very rare to need it, it is however very popular in VB.NET and a swan song because it is the default event and a double-click trivially adds the event handler. You only ever really need Load when you are interested in the actual window size after user preferences and autoscaling is applied. Everything else belongs in the constructor.
  • Update to Windows 8 or later, they have this wow64 problem solved.

这篇关于VS2010 在 64 位版本的 Windows 上的 WinForms 应用程序中不显示未处理的异常消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆