【问题标题】:What is the "Weak Event" pattern used in WPF applications?WPF 应用程序中使用的“弱事件”模式是什么?
【发布时间】:2009-02-05 16:20:31
【问题描述】:

WindowsBase DLL 定义了带有摘要的IWeakEventListener 事件:

为希望通过 WeakEvent 模式和 System.Windows.WeakEventManager 接收事件的类提供事件侦听支持。

这种模糊的描述并没有描述“弱事件模式”实际上是什么。

那么,这种模式是什么,为什么要使用它,它在 WPF 应用程序之外有用吗?

编辑 已经有一些很好的答案,但是没有人谈论过这种模式在 WPF 应用程序之外是否有用。在我看来,弱事件模式(如依赖属性)与 WPF API 和 DLL 有着千丝万缕的联系。是否有可用于非 WPF 应用程序的等效实现?

【问题讨论】:

  • 我认为弱引用是解决问题的一种更通用的方法,可以在 WPF 之外使用。似乎 WeakEventManager 是 WPF 事件处理的弱引用的特殊案例。

标签: .net wpf events design-patterns weak-events


【解决方案1】:

重要的一点在备注中:

遵循的主要原因 WeakEvent 模式是当事件发生时 source 的对象生命周期为 可能独立于事件 听众。使用中心事件 调度一个 WeakEventManager 允许侦听器的处理程序是 垃圾收集即使来源 对象仍然存在

所以如果你有publishersubscriber 对象,那么通常在subscriber 订阅publisher 的事件之后,subscriber 不能被垃圾回收。弱事件模式使两个“弱”之间的链接(如WeakReference),因此不存在这种依赖关系。 (另一种方法是在subscriber 想要获得垃圾收集的资格时取消订阅该事件,但这会变得混乱。)

【讨论】:

  • 到底是怎么弄得乱七八糟的?
  • @zvolkov:因为突然之间,订阅者需要知道什么时候有资格进行垃圾收集,这通常会导致额外的知识在整个系统中传播,并且突然间,您失去了 自动 垃圾收集的一半好处。
  • 同意,取消订阅的处理程序确实会变得混乱。但是,“WeakReference”也必须有一些开销!至少我能想到的是,当对象从内存中移除时,GC 需要做的额外工作是将弱引用对象重置为 null。
  • 例如,这是否意味着当我订阅窗口的位置更改事件时,我需要使用弱事件模式,否则其中的对象在窗口被 GC 之前不能被垃圾收集?
  • @JamesJoshuaStreet:嗯,或者你需要在适当的时候手动取消订阅,是的。
【解决方案2】:

WeakEvent Patterns

订阅事件可能会导致订阅者未被收集。您会假设该对象将被收集,因为您没有其他对它的引用 - 但是事件发布者持有侦听器对象并将其保存在内存中(除非它明确取消订阅,在这种情况下,您需要确切知道何时退订)。有管理的泄漏。

作为一个经验法则,如果事件发布者的等待时间比侦听器长,您可能会遇到这个问题,应该检查一下。

WeakEvents 应该可以帮助您,因为如果对它的唯一活动引用是“弱”,则该对象将被收集。仅当您计划开发新控件时才应关注此模式,这通常会暴露大量事件。

基本思想类似于 WeakReference w.r.t。垃圾收集。

【讨论】:

    【解决方案3】:

    在 .NET 4.5 中,改进了对建立对事件的弱引用的支持。

    代替

    source.Event += OnEvent;
    

    您可以使用新的WeakEventManager<TEventSource, TEventArgs>

    WeakEventManager<EventSource, EventArgs>.AddHandler(source, "Event", OnEvent);
    

    Read more here.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-30
      • 2018-08-03
      • 1970-01-01
      相关资源
      最近更新 更多