WeakEvent and WeakReference

为什么实现 WeakEvent 模式?

侦听事件可能会导致内存泄漏。侦听事件的一般方法是使用语言特定的语法,该语法将处理程序附加到源上的事件。例如,在 C# 中,该语法是:source.SomeEvent += new SomeEventHandler(MyEventHandler)

此方法创建从事件源到事件侦听器的强引用。通常,为侦听器附加事件处理程序会导致侦听器具有对象生存期,该生存期受源的对象生存期影响(除非显式移除了事件处理程序)。但在某些情况下,您可能希望侦听器的对象生存期仅受其他因素(例如对象生存期当前是否属于应用程序的可视化树)控制,而不受源的生存期控制。如果源对象生存期超出了侦听器的对象生存期,则常规事件模式会导致内存泄漏:侦听器保持活动状态的时间比预期要长。

WeakEvent 模式旨在解决此内存泄漏问题。当侦听器需要注册事件,而该侦听器并不明确了解什么时候注销时,以及源的对象生存期超出侦听器的"有用"对象生存期时,可以使用 WeakEvent 模式。("有用"的概念由您自己定义。) 使用 WeakEvent 模式,侦听器可以注册和接收事件,同时不会对侦听器的对象生存期特征产生任何影响。实际上,在决定侦听器是否适合进行垃圾回收时,来自源的隐含引用不会计算在内。该引用为弱引用,仅是 WeakEvent 模式和相关 API 的命名。可以对侦听器进行垃圾回收或销毁,在不保留对现在销毁的对象的非可收集处理程序引用的情况下,源可以继续。

谁应实现 WeakEvent 模式?

实现 WeakEvent 模式主要是对于控件作者而言是很有趣味的。这是因为控件作者主要负责控件的行为和包容以及控件对其所插入到的应用程序的影响。这包括控件对象生存期行为,特别是对所描述的内存泄漏问题的处理。

某些方案本质上是将自己借给 WeakEvent 模式的应用程序。数据绑定就是这样的方案之一,在数据绑定中,作为数据源的源对象通常完全独立于作为绑定目标的侦听器对象。WPF 数据绑定的许多方面在实施事件的方式上已应用了 WeakEvent 模式。

如何实现 WeakEvent 模式?

实现 WeakEvent 模式由三个方面组成:

  • WeakEventManager 类派生一个管理器。
  • 在任何想要注册弱事件的侦听器的类上实现 IWeakEventListener 接口,而不生成源的强引用。
  • 注册侦听器时,对于想要侦听器使用该模式的事件,不要使用该事件的常规的 add remove 访问器,请在该事件的专用 WeakEventManager 中改用"AddListener""RemoveListener"实现。

 

弱引用

表示弱引用,即在引用对象的同时仍然允许垃圾回收来回收该对象。

弱引用特别适合以下对象:占用大量内存,但通过垃圾回收功能回收以后很容易重新创建。

假设 Windows 窗体应用程序中的一个树视图向用户显示了复杂的选项层次结构。 如果基础数据量很大,则用户使用应用程序中的其他部分时,在内存中保留该树会导致效率低下。

当用户切换到应用程序的其他部分时,可使用 WeakReference 类来创建对该树的弱引用,并销毁所有强引用 当用户切换回该树时,应用程序会尝试获得对该树的强引用,如果得到,就不必重新构造该树。

由于在 IsAlive 属性返回 true 之后,可能会立即通过垃圾回收来回收对象,也就是Target=null,因此不建议使用此属性(除非仅对 false 返回值进行测试)。 尽管这种概率很小。

 

 

你可能感兴趣的:(WeakReference)