【问题标题】:PropertyChangedEventManager: AddHandler vs AddListenerPropertyChangedEventManager:AddHandler 与 AddListener
【发布时间】:2019-02-05 03:10:39
【问题描述】:

here 所述,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)

listenerhandler 设置为null。

我需要使用强事件处理程序(即source.PropertyChange += handler;)更改一些代码以遵循弱模式。使用AddHandler 方法很简单。有什么理由更喜欢AddListener(这需要我实现IWeakEventListener)?

如果我要编写新代码,为什么会更喜欢其中一个?

【问题讨论】:

  • 据我所见,AddListener 的成本略低,但并不显着。似乎AddHandler 会更容易创建自己的泄漏(查看您需要如何跟踪委托)
  • @CoryNelson 但是“弱事件模式”的目的不是避免泄漏吗?我会假设这两种实现都是这样做的。或者,“需要跟踪代表”是什么意思?这就是你必须为正常事件做的事情——但不是在这里,或者?无论哪种情况,监听器还是处理程序?

标签: c# wpf events inotifypropertychanged


【解决方案1】:
AddHandler(...

只是 .Net 4.5 的一个功能,它可以简化常见情况的代码。 因此,如果满足要求,是更好的选择。

.Net4.5 之前只有:

AddListener(...

您可以在以下来源中找到更多信息:

  1. Book - Introducing .NET 4.5:

...不再需要创建自定义 WeakEventManager 或实现 IWeakEventListener...

  1. Blog post - Weak event pattern improvements:

在 WPF 4.5 RC 中,弱事件模式得到了改进。此外 监听器,WeakEventManagers 也支持 Handlers。处理程序是 像事件处理程序一样定义,但我们的类不需要实现 特定的界面。另外,因为没有硬引用 维护,没有可能的内存泄漏。


旁注:

根据我的经验,这些解决方案并非万无一失,如果您或您团队中的某个人使用 lambda-expression 作为处理程序,您仍然可能会出现内存泄漏。

当使用 lambda 表达式时,编译器生成匿名类作为目标(新生成的类包装 lambda 表达式)。 GC 会立即收集对此类的弱引用。

这里是Thomas Levesque explanation

特殊情况:匿名方法处理程序 如果您订阅 使用匿名方法(例如 lambda 表达式)的事件,请确保 保留对处理程序的引用,否则它也会被收集 很快……

p.s 我最终使用了与Thomas Levesque 解决方案类似的方法,并且为了保护团队免于注册 lambda,我检查(通过反射)每个处理程序是否是匿名方法。如果是,我会抛出一个异常 - 所以开发人员立即知道这是不可接受的,并更改他们的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多