【问题标题】:WPF MVVM DataBindings stop updatingWPF MVVM DataBindings 停止更新
【发布时间】:2012-09-03 12:29:12
【问题描述】:

我正在开发一个利用 MVVM 模式的中型 WPF 应用程序。 ViewModel 使用INotifyPropertyChanged 来刷新它们各自的视图。

这种方法非常有效,除了一个问题:当这个应用程序长时间运行(3-7 天)时,视图(整个应用程序中的每个视图!)突然停止更新它们的绑定属性。

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

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

总结:经过很长一段时间,Views 停止更新其数据绑定,但 ViewModels 仍在调用 PropertyChanged 事件。

有什么建议吗???

【问题讨论】:

  • 有什么建议吗? - 认真考虑按计划重启。 WPF 是一种客户端技术,我不希望它能够 24x7 全天候运行。
  • 棘手。在那种情况下,我会选择@HenkHolterman,尽管首先找出为什么会发生这种情况会很有趣......
  • 您也可以使用snoop 或类似工具在问题出现时查看该应用程序。它有助于解决损坏的绑定等问题。我不确定在这种情况下我会期望它揭示什么,但它可能会带来一些启示。
  • @HenkHolterman:我想我已经运行了几个月的 WPF 应用程序,最终杀死它们的通常是ExecutionEngineException
  • 该应用程序的工作集内存是什么样的?页面错误怎么办?

标签: c# wpf data-binding mvvm inotifypropertychanged


【解决方案1】:

经过几个月的调试,我终于能够通过将调试器附加到远程目标来解决问题。只有这样它才会产生一个我可以调试的异常。我仍然不明白为什么 AppDomain.UnhandledException 和 Dispatcher.UnhandledException 没有捕捉到这个异常,但至少我能够弄清楚。

【讨论】:

  • 你能详细说明一下吗?
  • 菲利普,我希望我能给你更多,但这个问题很可怕。我从来没有真正理解过根本原因,但这里是我更详细的发现(见下一篇文章)。
  • 我发现当使用 .ToString() 将等于 NaN 的双精度值转换为字符串时,在此应用程序的另一部分中引发了异常。我认为这个异常应该被 AppDomain.UnhandledException 或 Dispatcher.UnhandledException 捕获,但由于某种原因它从来没有,所以我花了一段时间才找到它。第一次引发此异常时,数据绑定停止更新。显然数据绑定框架中的某些东西崩溃了,但我不明白为什么我没有在其他地方得到异常来指示失败。
  • 然而,在修复了转换之后(我现在在转换之前检查 NaN),数据绑定一直可靠地工作。我希望我能给你更多,但希望这能指引你正确的方向。
【解决方案2】:

您可能会成为过度热心的弱引用的受害者。您的 MVVM 框架可能有一个修复程序。如果没有,此信息可能会帮助您在源代码中找到问题。

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

所以为了解决这个问题,许多 MVVM 框架使用weak references for events。虽然这可以修复内存泄漏,但它也可能导致您看到的问题。如果弱事件未正确实现,则可能在实际收集 XAML 控件之前将其删除。

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

【讨论】:

  • 感谢您的评论!我正在调查你所说的,并试图通过定期调用 GC.Collect() 来触发问题。您关于收集弱引用的想法听起来完全像我看到的症状......不幸的是,我没有使用任何外部 MVVM 框架,所以我发现的任何错误都可能在 .NET 框架本身内。这个问题最难的部分是它只会在几天或几周内发生,所以试图重现它是非常令人沮丧的。
  • 这个块可能会帮助你(避免使用 DataBinding 的 WPF 内存泄漏(黑魔法)):blogs.msdn.com/b/micmcd/archive/2008/03/07/…
猜你喜欢
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 2020-08-09
  • 2016-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多