正如所述的这里,PropertyChangedEventManager类
提供一个WeakEventManager实现,以便您可以使用“弱事件侦听器”模式为PropertyChanged事件附加侦听器。
有两种方式可以订阅属性更改:
void AddHandler (INotifyPropertyChanged source, EventHandler<PropertyChangedEventArgs> handler, string propertyName)
void AddListener (INotifyPropertyChanged source, IWeakEventListener listener, string propertyName)最后,它们都调用了相同的方法:
private void AddListener(INotifyPropertyChanged source, string propertyName, IWeakEventListener listener, EventHandler<PropertyChangedEventArgs> handler)将listener或handler设置为null。
我需要用强事件处理程序(即source.PropertyChange += handler;)修改一些代码,以遵循弱模式。使用AddHandler方法是很简单的。是否有任何理由选择AddListener (这要求我实现IWeakEventListener)?
如果我要编写新代码,有什么理由选择其中一种而另一种呢?
发布于 2020-06-28 11:29:06
AddHandler(...它只是一个简单的.Net 4.5特性,它来简化您的代码以适应普通情况。因此,一个更好的选择,如果满足要求。
在.Net4.5之前,只有:
AddListener(...您可以在以下来源找到更多信息:
..。不再需要创建自定义WeakEventManager或实现IWeakEventListener.
在WPF 4.5 RC中,弱事件模式得到了改进。除了侦听器之外,WeakEventManagers还支持处理程序。处理程序是像事件处理程序一样定义的,但是我们的类不需要实现特定的接口。另外,由于没有维护硬引用,因此不存在可能的内存泄漏。
边注:
根据我的经验,这些解决方案并不是防弹的,如果您或您的团队中的某个人使用lambda表达式作为处理程序,则仍然会出现内存泄漏。
当使用lambda表达式时,编译器生成匿名类作为目标(新生成的类包装lambda表达式)。GC将立即收集对该类的弱引用。
特例:匿名方法处理程序如果您使用匿名方法(例如lambda表达式)订阅事件,请确保保持对处理程序的引用,否则它将很快被收集.
最后,我使用了与托马斯·莱韦斯克解决方案类似的方法,并且为了保护团队不向lambda注册,我检查了(使用反射)每个处理程序,如果它是一个匿名方法的话。如果是的话,我会抛出一个异常-因此开发人员立即知道这是不可接受的,并更改他们的代码。
https://stackoverflow.com/questions/52092516
复制相似问题