【发布时间】:2020-06-26 18:41:43
【问题描述】:
我将 WPF 与 MVVM 一起使用。我有一个 ViewModel 将对象 MyService 实例化为属性。 ViewModel 订阅了MyService 的事件。 MyService 属性绑定到 View 中的某些元素。
当ViewModel 不再使用时,MyService 是否会因为事件订阅而使我的ViewModel 保持活动状态并阻止垃圾收集 (GC)? 如果是,是否存在解决这个问题的简单方法?我应该在哪里取消订阅MyService? (虽然我无法控制调用我的 View/Viewmodel 的那个)
public class ViewModel
{
public MyService MyService { get; set; } = new MyService();
public ViewModel()
{
MyService.MyEvent += OnMyEvent;
}
private void OnMyEvent(object sender, EventArgs e)
{
// do something
}
}
【问题讨论】:
-
绑定将使用弱引用来订阅事件,所以如果你正确地处理你的虚拟机,那么就不会有问题。话虽如此,VM可能在GC的Gen2,然后它会在那里徘徊一段时间,通常是10分钟。如果您有内存泄漏,那么我建议使用适当的工具(我使用的是 ANTS 免费版)并找到对您的服务的引用。可能是其他地方的另一个实例?
-
@XAMlMAX
Bindng没有使用弱引用。它使用了对Binding.Source的强引用。事实上,如果你绑定到一个没有实现INotifyPropertyChanged的源,绑定引擎会创建一个静态字段来引用源。由于静态内存永远不会被垃圾收集,因此您会引入内存泄漏。这就是为什么绑定源“必须”实现INotyfyPropertyChanged甚至更好的原因(就性能而言,实现DependencyProperty。 -
@XAMlMAX 但是
Binding使用弱事件模式以便使用PropertyChangedEventManager监听PropertyChanged事件。