Unsubscribe from events in observableCollection

Lets say I have an observableCollection of classes:

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

When I will remove items from a collection, do i need manually unsubscribe from events(OnSomeEvent) or should I leave it for a GC? And what is the best way to unsubscribe?


If you expect your item to be collected then yes you need to unsubscribe.

To do so, the usual way is:

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;
        }
    }
}

You don't need to unsubscribe in normal case.

The event subscriber cannot prevent the publisher ( testClass ) from being collected, but the opposite can happen. I cannot see anything keeping the testClass alive, except the ObservableCollection .

testClass.SomeEvent += this.OnSomeEvent;

testClass is keeping this alive because this is stored in testClass.SomeEvent 's invocation list (such that OnSomeEvent is called when there is a SomeEvent ). this will not keep testClass alive by subscribing testClass 's event.

In the following code, the obj is removed from the collection, and it is garbage collected without unsubscribing, you may try to run the code to see the result:

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");
}

Output:

True
False

You may take a look in a similar question.

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

上一篇: 在EventHandler中使用foreach迭代器值

下一篇: 取消订阅observableCollection中的事件