I have a view model which retrieves an object from some service, and makes it available for data binding. The object is implementing INotifyPropertyChanged
. In the view model, I am listening to the PropertyChanged
event to perform some internal actions when certain properties in the object are modified.
Now it is possible that a new object is requested from the service, completely replacing the old object. Given that the lifetime is essentially limited by the view model itself, and nobody else holds a reference to it (WPF uses weak listeners), do I need to unsubscribe from the object in this case? Of course, I should and it’s simple enough to do so in the setter, but do I really need to?
public class MyViewModel : INotifyPropertyChanged
{
private DataType myData;
public DataType MyData
{
get { return myData; }
protected set
{
if (value == myData)
return;
if (myData != null)
myData.PropertyChanged -= DataPropertyChanged;
myData = value;
myData.PropertyChanged += DataPropertyChanged;
OnNotifyPropertyChanged("MyData");
}
}
public void UpdateData ()
{
MyData = service.GetData();
}
// ...
}
In order to prevent resource leaks, you should unsubscribe from events before you dispose of a subscriber object. Until you unsubscribe from an event, the multicast delegate that underlies the event in the publishing object has a reference to the delegate that encapsulates the subscriber's event handler.
+= subscribes to an event. The delegate or method on the right-hand side of the += will be added to an internal list that the event keeps track of, and when the owning class fires that event, all the delegates in the list will be called.
You don't really need to do anything, but you should detach the old object from the event when you're done. For two reasons.
If the object is garbage collected and the event is fired, some time is going to be spent figuring out the object is no longer alive. Hopefully it will then be removed from the event handler list. If not, some more time is going to be spent the next time, too, and so on.
More importantly, if your old object is not garbage collected and the event is fired, you're going to get two event notifications - once in the old object and once in the new one. You will need to handle this case specifically in the old object (or else, bad things will happen).
Easiest way to handle this is to detach from the event when you're done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With