gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 08:23:21 31 4
gpt4 key购买 nike

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

An unhandled exception of type 'System.NullReferenceException' occurred in PresentationFramework.dll

Additional information: Object reference not set to an instance of an object.

只有在应用程序的生命周期中,我通过我设置的某个进程打开一个子窗口时才会发生这种情况。该窗口存在于另一个程序集中,该程序集在运行时使用 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 以完全相同的方式处理它们,因为它们具有完全相同的原因,终结器不会做任何其他事情来使区别更清楚。非托管代码与托管代码一样容易受到空指针的攻击。更重要的是,堆损坏是一个非常常见的原因。
  • finalizer 已经捕获了所有异常,但是 NRE 是 critical exception所以它重新抛出它,这就是你的程序的结尾。

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

而且此类崩溃的重复率很低,这是您难以自己重现的核心原因。浏览器中最常见的麻烦制造者是加载项、ActiveX 控件(如 Flash)和反恶意软件。如果您无法控制导航的网站类型,您将遇到额外的麻烦,有很多网站会故意探测浏览器的漏洞。

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

关于c# - 关闭 WPF 应用程序时出现未处理的 NullReference 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23390968/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com