使用弱事件实现的NotifyParentObservableCollection

在软件开发中,事件是组件间通信的一种常用机制。然而,如果事件的订阅者和发布者之间存在强引用,可能会导致内存泄漏。本文将介绍如何使用弱事件模式重构NotifyParentObservableCollection,以避免这种内存泄漏问题。

在之前的文章中,介绍了一个名为NotifyParentObservableCollection的集合类,它能够将子元素的INotifyPropertyChanged事件转发给感兴趣的监听者。然而,这个实现使用了强引用,这可能会导致内存泄漏。在这篇文章中,将展示如何使用弱事件模式来解决这个问题。

弱事件模式

弱事件模式是一种避免内存泄漏事件管理机制。它通过使用弱引用来引用事件的订阅者,从而允许垃圾回收器在适当的时候回收订阅者对象。微软的WeakEventManager类和IWeakEventListener接口提供了一种实现弱事件模式的方法。

重构NotifyParentObservableCollection

为了实现弱事件模式,首先将原来的NotifyParentObservableCollection类重命名为StrongNotifyParentObservableCollection,然后重新实现了NotifyParentObservableCollection类。以下是实现的步骤:

创建了两个弱事件管理器类:ChildPropertyChangedEventManager和AnyPropertyChangedEventManager。这些类继承自WeakEventManager,并实现了IWeakEventListener接口。

public class AnyPropertyChangedEventManager : WeakEventManager { private AnyPropertyChangedEventManager() { } public static void AddListener(INotifyPropertyChanged source, IWeakEventListener listener) { CurrentManager.ProtectedAddListener(source, listener); } public static void RemoveListener(INotifyPropertyChanged source, IWeakEventListener listener) { CurrentManager.ProtectedRemoveListener(source, listener); } protected override void StartListening(object source) { ((INotifyPropertyChanged)source).PropertyChanged += DeliverEvent; } protected override void StopListening(object source) { ((INotifyPropertyChanged)source).PropertyChanged -= DeliverEvent; } private static AnyPropertyChangedEventManager CurrentManager { get { var managerType = typeof(AnyPropertyChangedEventManager); var manager = (AnyPropertyChangedEventManager)GetCurrentManager(managerType); if (manager == null) { manager = new AnyPropertyChangedEventManager(); SetCurrentManager(managerType, manager); } return manager; } } }

在NotifyParentObservableCollection类和ViewModel类中,实现了IWeakEventListener接口的ReceiveWeakEvent方法。这个方法会在子元素的属性发生变化时被调用。

public bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e) { if (managerType == typeof(AnyPropertyChangedEventManager)) { OnChildPropertyChanged(this, sender, ((PropertyChangedEventArgs)e).PropertyName); } return true; } private void AttachHandlers(IEnumerable items) { if (items != null) { foreach (var item in items.OfType()) { AnyPropertyChangedEventManager.AddListener(item, this); } } } private void DetachHandlers(IEnumerable items) { if (items != null) { foreach (var item in items.OfType()) { AnyPropertyChangedEventManager.RemoveListener(item, this); } } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485