取消订阅observableCollection中的事件

可以说我有一个observableCollection类:

CustomClassName testClass = new CustomClassName();
ObservableCollection<CustomClassName> collection = new ObservableCollection<CustomClassName>();
testClass.SomeEvent += OnSomeEvent;
collection.add(testClass);

当我从集合中删除项目时,是否需要手动取消订阅事件(OnSomeEvent),还是应该将它留给GC? 什么是退订的最佳方式?


如果您希望收集物品,那么您需要退订。

要做到这一点,通常的做法是:

collection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(collection_CollectionChanged);

// ...
// and add the method
void collection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
    {
        foreach (var it in e.OldItems) {
            var custclass = it as CustomClassName;
            if (custclass != null) custclass.SomeEvent -= OnSomeEvent;
        }
    }
}

正常情况下不需要退订。

事件订阅者不能阻止收集发布者( testClass ),但相反的情况可能发生。 除了ObservableCollection ,我看不到任何保持testClass活着的东西。

testClass.SomeEvent += this.OnSomeEvent;

testClass是保持this活,因为this是存储在testClass.SomeEvent的调用列表(这样OnSomeEvent时,有一个被称为SomeEvent )。 this不会通过订阅testClass的事件来保持testClass的活动。

在下面的代码中, obj已从集合中删除,并且在不取消订阅的情况下进行垃圾收集,您可以尝试运行代码以查看结果:

void Main()
{
    var obj = new BackgroundWorker();
    obj.DoWork += OnSomeEvent;
    var oc = new ObservableCollection<object>{ obj };

    WeakReference objRef = new WeakReference(obj);
    Console.WriteLine(objRef.IsAlive);

    oc.Remove(obj);
    obj = null;
    GC.Collect();

    Console.WriteLine(objRef.IsAlive);
}

private void OnSomeEvent(object sender, DoWorkEventArgs e)
{   
    Console.WriteLine("work");
}

输出:

真正

你可以看看类似的问题。

链接地址: http://www.djcxy.com/p/51435.html

上一篇: Unsubscribe from events in observableCollection

下一篇: C# Lambda expressions: Why should I use them?