关闭WPF应用程序时出现未处理的NullReference异常
本文关键字:未处理 NullReference 异常 WPF 应用程序 关闭 | 更新日期: 2023-09-27 18:01:12
当我关闭最后一个窗口时,我的应用程序中出现了一个未处理的异常:
"System.NullReferenceException"类型的未处理异常出现在PresentationFramework.dll 中
附加信息:对象引用未设置为对象
只有当我在应用程序的生命周期中通过我设置的某个进程打开子窗口时,才会发生这种情况。该窗口存在于另一个程序集中,该程序集在运行时使用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类是一个围绕COM组件InternetExplorer的包装器
- 虽然该异常具有托管异常名称,但它不是由托管代码引起的。终结器已经检查了null引用,是Internet Explorer在后台抛出了一个非托管的AccessViolationException。CLR以完全相同的方式处理这些问题,因为它们有完全相同的原因,终结器不会以其他方式使区别更清楚。非托管代码和托管代码一样容易受到空指针的攻击。更重要的是,堆损坏是一个非常常见的原因
- 终结器已经捕获了所有异常,但是NRE是一个关键异常,所以它会重新抛出它,这就是程序的结束
使用WebBrowser是一种负担,浏览器通常很容易崩溃。当你在应用程序中使用控件时,这种情况会被放大,它在进程中运行,并且没有Internet Explorer本身使用的那种崩溃保护。因此,浏览器中出现的任何错误都将直接影响应用程序的稳定性,通常很难诊断崩溃原因,因为爆炸的是非托管代码。
这样的崩溃重复得很糟糕,这是你自己很难得到指责的核心原因。浏览器中最常见的麻烦制造者是加载项、ActiveX控件(如Flash(和反恶意软件。如果你不能控制导航的网站类型,你会遇到额外的麻烦,有很多网站会故意探测浏览器的漏洞。
您可以使用一种特定的对策,即在不再使用控件时调用该控件的Dispose((方法。通常在Window的Closing事件处理程序中。这将立即注销COM事件并触发崩溃,现在你可以抓住它了。当这种情况发生时,请强烈考虑关闭你的程序,你的进程中确实有一具尸体,当你试图复活它时,它会变成僵尸。
我在一个应用程序中遇到了同样的问题,但从未发现背后的真正问题。但我找到了这个应用程序的解决方法。在主窗口的关闭事件中,我实现了一个循环,以前关闭了所有其他窗口。然后它起作用了。也许这对你也有用。如果你找到原因,那就更好了。