2014-04-30 58 views
12

我收到未处理的异常在我的应用程序,当我关闭最后一个窗口时:未处理NullReference异常关闭的WPF应用程序

型“System.NullReferenceException” 未处理的异常发生在PresentationFramework.dll

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

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

一些注意事项:

  • 这只是发生在某些机器/环境(我不能够辨别虽然模式)
  • 我对调度员在该应用中UnhandledException处理其捕获所有的未处理的例外。这并没有被抓住。

调用堆栈是:

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

有没有人见过这个,还是会有人知道如何调试呢?奇怪的是,没有调用堆栈,并且在程序退出时发生。

+0

我认为你需要编辑这个问题,在你的app.xaml文件中包含ShutdownMode。 –

+0

'ShutdownMode'属性设置为'OnMainWindowClose',但是在启动过程中会有几个对话框可以触发,所以在应用程序启动过程中它会暂时切换到'OnExplicitShutdown',但它总是**切换回**到主窗口打开之前的'OnMainWindowClose'。 – qJake

+0

我不知道是什么导致异常,但我会尝试通过从重定向Stderr/Stdio流的另一个应用程序中启动它进行调试,并且希望(绝对*希望*)在这些流中存在一个可以提供线索的artefact 。 –

回答

13

您的问题缺乏细节,堆栈跟踪很短,但提供了很多关于潜在问题的线索。一些可见的事实:

  • 终结器线程发生异常,堆栈跟踪如此之短的原因。终结器中未处理的异常是致命的,它们总是会终止程序。试图在代码中使用try/catch的原因没有效果。
  • 连接点cookie是一个COM术语,当您订阅COM事件时会得到一个。当您取消订阅事件时,该cookie需要再次使用,该事件发生在终结器中。在WPF中只有一个类使用它,即WebBrowser控件。 WPF类是Internet Explorer(COM组件)的一个包装器。
  • 异常虽然具有托管异常名称,但不是由托管代码引起的。终结器已经检查了空引用,它是Internet Explorer在引擎盖下抛出一个非托管的AccessViolationException。 CLR的处理方式与CLR完全相同,因为它们具有完全相同的原因,但终结器不会做任何其他操作来区分更清楚的事情。非托管代码与托管代码一样易受空指针的影响。更重要的是,堆腐败是一个非常普遍的原因。
  • 终结器已经捕获所有的异常,但NRE却是critical exception,所以它重新抛出它,这就是程序的结束。

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

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

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

+0

我确实使用WebBrowser控件(事实上,你能够辨别出来,只是从堆栈跟踪令人印象深刻),我会尝试亲自处理,看看是否能解决问题。仅供参考,该应用程序已经针对.NET 4,所以它必须像以前的版本一样处理事情。我在测试完成后会在这里更新。 – qJake

+0

好的,取消它,看起来好像刚刚移动了。 –

+0

看起来像是这个问题!我放置了WebBrowser并放弃了它的所有异常,并且现在应用程序关闭了。谢谢! – qJake

1

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

相关问题