被VS2012异常吞噬噩梦绊倒



我开始在这里问这个问题,得到了非常有启发性的答案,但仍然无法绕过这个问题。这个问题已经结束了,因为这是一个已知的问题。我知道这是一个已知的问题:我的问题是我能做些什么?

总结:

  1. VS调试器在Windows 64位系统(在我的例子中是Win 7 64位)上调试时,会吞下Form_Load事件(或从中进行的任何调用)中发生的未处理的异常。目前,这使得VS作为开发环境毫无用处
  2. 一个建议是将代码移动到构造函数中,而不是FOrm_Load事件中。我不想这样做,因为它将代码从视线之外转移到"设计师创建"的模块中;那些模块充满了我还不能更改的代码;我不相信设计师不会删除或更改我放在那里的代码
  3. 另一个建议是通过在初始过程(例如Sub-Main)中插入一些代码,将未处理的异常指向伪空异常处理程序这很有效。这里的问题是,只有当我关闭应用程序框架时,SubMain才能在启动时执行。然后,我无法在"直到主窗体或最后一个窗体关闭"的生存期内运行应用程序
  4. 认为我已经在启动表单中运行了一个SubMain,并在正确的时间运行(即在form_Load之前)。因此,我仍然可以使用应用程序框架,将此特殊代码放在其他代码之前运行。我可能错了。无论如何,我已经稍微更改了该表单的代码,Main不再及时运行——如果真的这样的话(form_Load首先运行,我们也有同样的问题)。尝试将代码移动到Form_Load中,但它本身会导致错误
  5. 有一个所谓的修补程序(KB976038)。我应用了它(需要重新启动):但现在我没有吞下异常,而是得到了一个vshost.exe应用程序错误,仍然无法调试我的代码。令人沮丧的是,一旦我确定了应用程序错误,我就会看到VS调试器显示了通常的"未处理的异常"框,但它在大约十分之一秒后就会消失

那么我的选择是什么?

这里的共同点是尽管我是一名经验丰富的程序员,习惯于在VB.NET和VB6中完成任务,并且能够理解导致此问题的原因的全面解释;

所有可能的措施都超出了我的能力,并且引入了太多我甚至可能都不知道的陷阱。我忍不住想,为什么我不能直接开始编码,并使用我可以信任的调试器来破解异常,来处理我将犯下的不可避免的编码错误?

目前,我觉得,如果(根据比我更专业的人的建议)我以某种方式让VS正确地捕捉未处理的异常并对其进行破坏,这将只是今天的。谁知道我明天或下周在代码中所做的某件事是否会打破精心构建的安全网,使VS暂时正常运行?

我坦率地承认,在我的.NET专业知识的这个阶段,我不应该被允许接近构造函数/设计器创建的代码。我只想把事情做完!所以我的选择看起来像:

  • 学习所有的核心内容,这样我就永远不会破坏这个问题的解决方案。这将需要数月甚至数年的时间;或
  • 放弃并返回XP上的VS2008 Express;或
  • 说服该公司放弃Windows 7 64,并将Windows 7 32作为开发操作系统

欢迎任何想法或建议!

编辑:正如下面@roadwarmor所建议的,以下是原始问题答案中建议的解决方法,以及我发现的问题:

1项目+属性,构建选项卡,将平台目标更改为AnyCPU

已经这样设置了,我无法更改它。尝试将TargetCPU从"AnyCPU"更改为x86或64位-没有效果。

2调试+异常,勾选CLR异常的抛出框

一旦我开始故意处理异常(我经常这样做),运行/测试就成了一场噩梦。无论是否处理,每个异常都将导致"停止"。

3在加载事件处理程序中写入try/catch

这也不会很有趣。在开发的这个阶段,我想看看导致问题的线路。总是讨厌在VB6中调试处于On Error Goto范围内的代码,有人将其放入调用堆栈的6个步骤中;我不想在我自己的项目中以这种方式开始!

4使用Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException)在Main()方法中,以便消息循环中的异常陷阱在调试模式下未禁用。但是,此设置会使所有未处理异常很难调试,ThreadException事件非常无用。

我不明白最后一句话中的注释。但类似的东西起了作用。正如Neolisk在回答我之前的问题时所建议的那样,我所做的是,在一个SubMain中:

Public Sub Main()
AddHandler Application.ThreadException, AddressOf ThreadExceptionHandler
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException)
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf UnhandledExceptionHandler
Form1.Show()
End Sub
Friend Sub ThreadExceptionHandler(sender As Object, e As System.Threading.ThreadExceptionEventArgs)
End Sub
Friend Sub UnhandledExceptionhandler(sender As Object, E As System.UnhandledExceptionEventArgs)
End Sub

这是我的neolisk代码版本,必须对其进行更改,因为在我的VS/.NET版本(20124.5)中,两个处理程序需要具有不同的签名。有两个问题:

a)如果不勾选"启用应用程序框架",我无法在启动时执行SubMain。一旦我这样做,Form1.Show显示表单,我们到达SubMain的末尾,随着应用程序的关闭,表单立即再次消失。我破坏了应用程序"设置"窗口的"关闭模式"设置,不知道如何再次恢复。

b)此代码有效,但我不知道为什么如何、它是否涵盖所有异常、它与我可能决定在"调试/异常"对话框中勾选/取消勾选的内容之间的关系,或者它在调试时或运行时可能有什么其他棘手的副作用。

5考虑您的代码是否真的属于Load事件处理程序。很少需要它,但它在VB6程序员中很受欢迎负载是一件大事。只有当您对用户偏好后的实际窗口大小感兴趣,以及应用自动缩放。其他一切都属于构造函数。

足够公平。作为一名前VB6程序员,我习惯于使用Form_Load,但让我们进步和学习新东西,并将代码移动到表单的new()构造函数中(希望我永远不会有一些代码真正包含在_Load事件中)。现在,当执行遇到问题行时,至少会显示一个异常对话框:但它位于一个新窗口"No source available(crlf)the call stack only contains external code"的顶部。在这种特殊的情况下,代码中的错误可以从我在这里看到的地方进行调试(这是一个愚蠢的拼写错误),但当事情变得更加复杂时,这样的调试将是一场噩梦:没有机会看到任何东西的状态

一般评论:

1.在我们拥有的一台Win7 32位计算机上运行此项目(不是我的机器),并且没有任何问题。这是我的首选解决方案-简单地停止使用Win7 64位进行开发。

2。类似"你很幸运,你有一个调试器"的评论如下有趣,但没有帮助。这是VS2012,据说是具有调试器的开发环境将不得不支付%。我已经编程了足够长的时间知道我什么时候知道我在做什么我不该做的事,因为我不明白特别不明白的不是底层结构(I在ZX81机器代码上剪了我的牙,不想回到那里…),而是VS本身。我很高兴了解更多关于改变的信息VS中的异常处理程序,我需要,但绝对不想无知地直接潜入那里,作为我发展的基础环境

您的问题是重复的,而不是因为这是一个已知的问题。最初的问题由Hans Passant给出了一个很好的答案,讨论了可能的解决方案。

请让我们知道各种变通方法中的哪些是"核心"的,我将尝试提供简单的解释。事实上,我认为进一步探索这一点对你来说是件好事,因为这将提高你对幕后发生的事情的理解。

关于您的问题#3:尝试使用ShowDialog()而不是Show(),它会使应用程序运行,直到关闭此(主)表单。我们有一个生产应用程序是这样运行的。如果你没有一个主要的形式,你可能需要重新考虑你的设计。

在退出x64之前,请考虑从2008 R2开始,没有32位版本的操作系统。这意味着,如果你要在应用程序服务器上运行软件,那将是x64,所以你必须适应它。