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