Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PropertyChangedEventManager: AddHandler vs AddListener

As stated here, the PropertyChangedEventManager class

Provides a WeakEventManager implementation so that you can use the "weak event listener" pattern to attach listeners for the PropertyChanged event.

There are two ways to subscribe for property changes:

void AddHandler (INotifyPropertyChanged source, EventHandler<PropertyChangedEventArgs> handler, string propertyName)
void AddListener (INotifyPropertyChanged source, IWeakEventListener listener, string propertyName)

They both end up calling the same method:

private void AddListener(INotifyPropertyChanged source, string propertyName, IWeakEventListener listener, EventHandler<PropertyChangedEventArgs> handler)

with either listener or handler set to null.

I need to change some code with strong event handlers (i.e. source.PropertyChange += handler;) to follow the weak pattern. This is trivial using the AddHandler method. Are there any reasons to prefer AddListener (which requires me to implement IWeakEventListener)?

If I were to write new code, what are the reasons to prefer one to the other?

like image 934
Eske Sparsø Avatar asked Aug 30 '18 08:08

Eske Sparsø


1 Answers

AddHandler(...

Is simply a .Net 4.5 feature, it comes to simplify your code for the common case. Hence a better choice if meet requirements.

Before .Net4.5 there was only:

AddListener(...

More information you can find in the following sources:

  1. Book - Introducing .NET 4.5:

... it is no longer necessary to create custom WeakEventManager or implement IWeakEventListener...

  1. Blog post - Weak event pattern improvements:

In WPF 4.5 RC, weak event pattern is improved. In addition to listeners, WeakEventManagers also support Handlers. The handlers are defined like event handlers but our classes don't need to implement a particular interface. Plus since there are no hard references maintained, there are no possible memory leaks.


Side Note:

From my experience these solutions are not bulletproof and you can still have memory leak if you or someone from your team using lambda-expression as the handler.

When using lambda expression the compiler generate anonymous class to act as target (the newly generated class wrap the lambda expression). Weak reference to this class will immediately be collected by the GC.

And here is Thomas Levesque explanation:

Special case: anonymous method handlers If you're subscribing to the event with an anonymous method (e.g. a lambda expression), make sure to keep a reference to the handler, otherwise it will be collected too soon...

p.s I ended up using similar approach to Thomas Levesque solution, and to protect the team from registration with lambda i checked (with reflection) every handler if it is a anonymous method or not. if it was, i throw an exception - so the developer knew immediately that this is not acceptable, and change their code.

like image 176
Oran Gerbovski Avatar answered Oct 16 '22 06:10

Oran Gerbovski