20

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

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

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

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

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

有什么建议???

4

2 回答 2

3

After several months of debugging, I was finally able to solve the issue by attaching a debugger to the remote target. Only then did it produce an exception that I could debug. I still do not understand why AppDomain.UnhandledException and Dispatcher.UnhandledException did not catch this exception, but at least I was able to figure it out.

于 2012-11-09T19:33:13.953 回答
1

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

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

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

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

于 2012-09-12T18:04:03.953 回答