我正在开发一个使用MVVM模式的中型WPF应用程序。ViewModels使用INotifyPropertyChanged
刷新各自的视图。
这种方法非常有效,除了一个问题:当这个应用程序长时间运行(3-7天)时,视图(整个应用程序中的每个视图!)突然停止更新其绑定属性。
如果我在ViewModels中设置了一个断点,它们就会愉快地运行,调用PropertyChanged
,就像什么都没有错一样。但是,如果我在视图绑定到的某个ViewModel对象的getter中设置了断点,则永远不会调用getter!
我在这一点上很困惑,甚至不知道如何正确调试这个问题。我已经检查了VisualStudio输出窗口中的数据绑定错误,但一切看起来都很正常。这几乎就像WPF数据绑定引擎在后台崩溃了一样。此应用程序还监视未处理的异常(AppDomain.UnhandledException
和Dispatcher.UnhandledException
),但没有引发异常。
摘要:长时间后,视图停止更新其数据绑定,但ViewModels仍在调用PropertyChanged事件
有什么建议吗???
经过几个月的调试,我终于能够通过将调试器附加到远程目标来解决这个问题。直到那时,它才产生了一个我可以调试的异常。我仍然不明白为什么AppDomain.UnhandledException和Dispatcher.UnhandledException没有捕捉到这个异常,但至少我能弄清楚。
您可能会成为过度热心的弱引用的牺牲品。您的MVVM框架可能已修复。如果没有,这些信息可能会帮助您在源代码中找到问题。
INotifyPropertyChanged的大多数实现中都存在已知的内存泄漏。视图模型对XAML控件的PropertyChanged处理程序的委托进行硬引用。该委托反过来对XAML控件进行硬引用。因此,只要视图模型存在,就无法收集控件。
因此,为了解决这个问题,许多MVVM框架对事件使用弱引用。虽然这可以修复内存泄漏,但也可能导致您看到的问题。如果弱事件没有正确实现,则可能会在实际收集XAML控件之前将其删除。
我怀疑您使用的是具有弱引用的MVVM框架,并且它们被过早地丢弃了。要查看这是否是一个可能的问题,请对GC.Collect()进行一些调用,看看问题是否更频繁地出现。