试图在我们的 WPF/MVVM 应用程序中追踪一些内存泄漏,我发生了一些事情......
如果您使用特定于实例的处理程序在其关联的 ViewModel 中侦听 ModelItem 事件,那么只要 ModelItem 仍然存在,这不会使 ViewModel 一直存在吗?
考虑这种情况...
public class ItemViewModel
{
public ItemViewModel(ModelItem item)
{
this.Item = item;
item.SomeEvent += ItemSomeEventHandler
}
Public ModelItem Item { get; private set; }
// Note: This is a handler on this instance, not a shared handler
private void ItemSomeEventHandler(object s, EventArgs e)
{
Console.WriteLine(“The model changed!”);
}
}
如果这确实导致泄漏,您如何/在哪里解开它? 你不能在"Dispose"中执行此操作,因为如果某些东西仍然有对它的引用,它不会被调用,它看起来像是:模型项。
正确的位置是在使用此 ViewModel 的控件中实现 Dispose,然后在那里涓滴一个事件解除钩子例程? 依靠外部的东西来确保清理自己的内部似乎有点危险,但是除了去EventManager架构之外,我不确定在这里该怎么做。
为什么不使用 WeakEvent/DelegateCommand?
它们实现对不需要确定性除权的委托的弱引用。
是的,它会导致泄漏......或者更具体地说,当视图不再显示时,不会收集ItemViewModel
,因为ModelItem
包含对ItemViewModel
的引用
您可以实现Dispose
并取消事件处理程序,如果您可以控制ViewModel
的生命周期,则事件处理程序完全有效。问题是哪个组件正在创建ItemViewModel
?如果是另一个视图模型,则可以将处置委托给该模型,或者如果视图创建了视图模型,则可以调用Dispose
方法。
但是,如果您像MVVMLight
工具包一样使用,则可以使用其ICleanup
界面或类似的东西。查看此其他答案以获取更多信息。