【问题标题】:Explain critical bug in Visual Studio 2010 and up, WinForms and WPF解释 Visual Studio 2010 及更高版本、WinForms 和 WPF 中的严重错误
【发布时间】:2012-10-21 03:32:18
【问题描述】:

尝试将以下代码放入 WinForms 的 Load 事件处理程序或 WPF 的 Loaded

Dim doc As New XmlDocument
Dim nsmgr As New XmlNamespaceManager(Nothing) 'this line throws an exception

问题是没有抛出异常,并且发生堆栈损坏。它可能有不同的副作用,具体取决于 IDE - 见下文。

  • 受影响的 IDE 是:2008、2010 和 2012(我可以测试的)。 2010 重置堆栈状态,并从子/处理程序返回,就像什么都没发生一样(但没有继续执行其他语句)。 2012 可能会警告用户有关失败的应用程序和在compatibility mode 中运行的尝试。之后的下一次运行与 2010 相同。2008 正确地引发异常,但仅在默认配置 (AnyCPU) 上。将平台目标切换到 x86 会使问题在 2008 年再次出现。
  • 受影响的框架是 WinForms 和 WPF。控制台应用程序和 ASP.NET 似乎工作正常。 .NET v2.0-4.5。
  • 到目前为止,受影响的范围仅为Load 事件。 将此代码放入按钮中即可使用。
  • 受影响的构建 配置=任何。尝试使用默认的 DebugRelease

为什么我认为这是一个错误,因为它会使对象处于不稳定状态——它们没有完成初始化,这不是预期的行为。关键是没有人会知道它发生了,因为它不会抛出异常。根据您的设计,您最终可能会在数据库中得到不正确的数据,在最坏的情况下可能会导致严重的后果。

有没有人很好地解释为什么会发生这种情况以及是否有解决方法?

【问题讨论】:

  • 哪个框架版本?尝试使用 4.0 的 LinqPAD 并按照文档的预期抛出异常
  • @Steve:全部可用,这意味着 .NET 2.0 到 4.5。我更新了问题。感谢您指出。
  • XmlNameSpaceManager的构造函数代码的第二行是this.xml = nameTable.Add("xml");,其中nameTable是传递给构造函数的参数,后面是无数同类型的调用。所以它应该立即抛出 NullReferenceException。确实非常奇怪的行为。
  • @Steve:确切地说,这就是它应该做的,以及它在 vs2008 上所做的。感谢您查看这个。也许,您也可以在 Visual Studio 中对其进行测试,看看是否可以重现?让我们确保不只是我的框架以某种方式损坏。还有谁能重现同样的问题?
  • 也许这解释了奥秘stackoverflow.com/questions/4933958/…

标签: wpf winforms form-load


【解决方案1】:

问题是由 wow64 仿真层引起的,当您在 x64 操作系统上以 x86 平台为目标时,该层会发挥作用。
它吞下负责触发 Load 事件的代码中的异常。
因此,调试器看不到异常,也无法介入处理这种情况。
This article seems to document 那里发生了什么,

来自 Hans Passant 的This previous answer(所有的功劳和赞成票都投给了它)解释了可能的解决方法。
我最喜欢的是将所有内容移出 Form_Load 事件并将有问题的代码放入表单构造函数中。 (当然不知道是否适用于你的情况)

【讨论】:

  • 我在Form_Loads 中有很多不同形式的代码,这些代码在历史上都存在。现在我有充分的理由重新考虑我的设计。感谢您挖掘它。
  • 我也在 VS 2008 上重新测试过,问题依然存在。为什么我之前没有发现它是因为 VS 2008 默认创建一个针对 AnyCPU 的应用程序,不像 2010 和 2012,默认是 x86。将 VS 2008 放到 x86 后,我遇到了同样的问题,所以它与 IDE 的选择完全无关。
猜你喜欢
  • 2011-04-15
  • 1970-01-01
  • 2012-03-27
  • 2013-07-04
  • 2019-05-17
  • 2014-02-22
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多