繁体   English   中英

关闭WPF应用程序时出现未处理的NullReference异常

[英]Unhandled NullReference exception when closing WPF application

当我关闭最后一个窗口时,我的应用程序中出现了未处理的异常:

PresentationFramework.dll中出现未处理的“System.NullReferenceException”类型异常

附加信息:未将对象引用设置为对象的实例。

只有在应用程序的生命周期中,我通过我设置的某个进程打开子窗口时才会出现这种情况。 该窗口存在于另一个程序集中,该程序集在运行时使用MEF动态加载,然后使用Castle进行实例化。 如果我然后调用某个方法,它会创建一个新的STA线程并打开一个WPF对话框窗口。

一些警告:

  • 这只发生在某些机器/环境中(虽然我无法识别模式)
  • 我在应用程序的调度程序上有一个UnhandledException处理程序,它捕获所有未处理的异常。 这没有被抓住。

调用堆栈是:

PresentationFramework.dll!MS.Internal.Controls.ConnectionPointCookie.Disconnect()
PresentationFramework.dll!MS.Internal.Controls.ConnectionPointCookie.Finalize()

有没有人见过这个,或者有人知道如何调试这个? 奇怪的是,没有调用堆栈,它在程序退出时正确发生。

你的问题没有细节,堆栈跟踪很短,但提供了很多线索来解决潜在的问题。 一些明显的事实:

  • 终结器线程发生异常,堆栈跟踪如此短暂的原因。 终结器中未处理的异常是致命的,它们将始终终止程序。 尝试在代码中使用try / catch的原因没有效果。
  • 连接点cookie是一个COM术语,当您订阅COM事件时,您将得到一个。 当你取消订阅事件时,需要再次使用该cookie,这在终结器中会发生。 WPF中只有一个类使用它,即WebBrowser控件。 WPF类是Internet Explorer的一个包装器,它是一个COM组件。
  • 该异常虽然具有托管异常名称,但不是由托管代码引起的。 终结器已经检查了空引用,它是Internet Explorer,它引发了一个非托管的AccessViolationException。 这些由CLR以完全相同的方式处理,因为它们具有完全相同的原因,终结器不会做任何事情来使区别更清楚。 非托管代码与托管代码一样容易受到攻击。 更重要的是,堆损坏是一个非常常见的原因。
  • 终结器已经捕获了所有异常,然而NRE是一个关键异常,因此它重新抛出它,这就是程序的结束。

使用WebBrowser是一种负担,浏览器通常容易崩溃。 当您在应用程序中使用该控件时,它会被放大,它在进程中运行,并且没有Internet Explorer本身使用的那种崩溃保护。 因此,浏览器中出现问题的任何内容都会直接影响应用程序的稳定性,因为它是非常难以诊断的崩溃原因,因为它是非托管代码。

这样的崩溃重演非常糟糕,这是你自己无法获得重复的核心原因。 浏览器中最常见的麻烦制造者是加载项,ActiveX控件(如Flash)和反恶意软件。 如果您无法控制导航的网站类型,那么您会遇到额外的麻烦,有很多可以故意探测浏览器的漏洞。

您可以使用一个特定的对策,当您不再使用它时调用控件的Dispose()方法。 通常在Window的Closing事件处理程序中。 这将立即取消注册COM事件并触发崩溃,现在您可以捕获它。 强烈考虑在发生这种情况时关闭你的程序,你的进程中确实有一个死尸,当你试图恢复它时会变成一个僵尸。

我在我的一个应用程序中遇到了同样的问题,从未发现它背后的真正问题。 但我找到了这个应用程序的解决方法。 在主窗口的Closing事件中,我实现了一个关闭所有其他窗口的循环。 然后它奏效了。 也许这对你也有用。 如果你找到它会更好的原因。

暂无
暂无

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

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