WPF MVVM 数据绑定停止更新

20

我正在开发一个中等规模的WPF应用程序,使用MVVM模式。 ViewModels使用INotifyPropertyChanged刷新它们各自的View。

这种方法非常有效,但有一个问题:当该应用程序长时间运行(3-7天)时,所有的Views(整个应用程序中的每一个View!)突然停止更新其绑定的属性。

如果我在ViewModels中设置断点,它们会很高兴地调用PropertyChanged,就好像没有任何问题一样。 但是,如果我在View绑定到的ViewModel对象的getter中设置断点,则getter永远不会被调用!

我现在被难住了,甚至不知道如何正确地调试此问题。 我已经检查了Visual Studio输出窗口中是否有数据绑定错误,但一切都看起来正常。 就好像WPF数据绑定引擎在后台崩溃了一样。 此应用程序还监视未处理的异常(AppDomain.UnhandledExceptionDispatcher.UnhandledException),但没有抛出任何异常。

总结:长时间运行后,View停止更新其数据绑定,但ViewModels仍在调用PropertyChanged事件。

有什么建议吗???


3
有什么建议吗?认真考虑定期重启。WPF是客户端技术,不要指望它可以24小时运行。 - H H
1
有点棘手。在这种情况下,我会选择@HenkHolterman的建议,尽管找出为什么会发生这种情况也很有趣... - Spontifixus
1
你也可以使用snoop或类似的工具,在问题出现时查看应用程序。它有助于解决损坏的绑定等问题。我不确定在这种情况下它会揭示什么,但它可能会帮助我们了解一些信息。 - default.kramer
1
@HenkHolterman:我想我之前曾经运行了几个月的WPF应用程序,最终导致它们崩溃的通常是ExecutionEngineException - H.B.
1
@H.B. - 可能有关,减少绑定/更新几个月 == 几天。一段时间后重复失败暗示存在资源泄漏。 - H H
显示剩余18条评论
2个回答

3

经过数月的调试后,我最终成功解决了这个问题,并通过将调试器附加到远程目标,才产生了一个可以调试的异常。我仍然不明白为什么AppDomain.UnhandledException和Dispatcher.UnhandledException无法捕获此异常,但至少我找到了解决方法。


你能否提供更多细节来扩展这个问题? - Philip Pittle
菲利普,我希望我有更多可以给你的东西,但这个问题很棘手。我从来没有真正理解它的根本原因,但以下是我发现的一些更详细的信息(请参见下一篇帖子)。 - shansen
我发现在应用程序的另一个部分中,当将一个等于NaN的double值使用.ToString()转换为字符串时,会抛出异常。我认为这个异常应该被AppDomain.UnhandledException或Dispatcher.UnhandledException捕获,但由于某种原因它从未被捕获,所以我花了一些时间才找到它。当第一次抛出此异常时,数据绑定停止更新。显然,数据绑定框架内部出现了问题,但我不明白为什么没有在其他地方得到异常来指示失败。 - shansen
然而,在修复了类型转换问题后(我现在在进行转换之前检查NaN),数据绑定始终可靠地工作。我希望我能提供更多信息,但希望这可以指引您朝着正确的方向前进。 - shansen

1

你可能正在遭受过度热情的弱引用的影响。你的MVVM框架可能有解决方法。如果没有,这些信息可能会帮助你在源代码中找到问题。

大多数INotifyPropertyChanged实现中都存在已知的内存泄漏问题。视图模型对XAML控件的PropertyChanged处理程序的委托进行了硬引用。该委托反过来又对XAML控件进行了硬引用。因此,只要视图模型存在,控件就无法被收集。

因此,许多MVVM框架使用事件的弱引用来解决此问题。虽然这可以解决内存泄漏问题,但也可能导致您看到的问题。如果弱事件没有正确实现,它可能会在XAML控件实际被收集之前被删除。

我怀疑你正在使用带有弱引用的MVVM框架,并且它们被过早地处理了。为了确定这是否是一个可能的问题,请调用几个GC.Collect()并查看问题是否更频繁发生。


谢谢您的评论!我正在研究您所说的内容,并尝试通过定期调用GC.Collect()来触发问题。您提到弱引用被收集的想法,听起来非常像我正在遇到的症状...不幸的是,我没有使用任何外部MVVM框架,因此我发现的任何错误可能在.NET框架本身内部。这个问题最困难的部分是它只会在几天或几周后出现,因此尝试复制它非常令人沮丧。 - shansen
这个代码块可能会对你有所帮助(避免使用数据绑定(黑魔法)导致的WPF内存泄漏):http://blogs.msdn.com/b/micmcd/archive/2008/03/07/avoiding-a-wpf-memory-leak-with-databinding-black-magic.aspx - Morten Frederiksen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接