PropertyChangedEventManager: AddHandler vs AddListener
Asked Answered
M

1

10

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?

Motherless answered 30/8, 2018 at 8:32 Comment(2)
From what I can see, AddListener is slightly less expensive but not significantly so. It seems like AddHandler would be easier to create your own leaks with (seeing how you need to keep track of a delegate)Mercorr
@CoryNelson But isn't the intention of the "weak event pattern" to avoid leaks? I would assume both implementations do so. Or, what do you mean with "need to keep track of a delegate"? That's what you have to do for normal events - but not here, or? In either case, listener or handler?Aerophagia
P
8
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.

Populous answered 28/6, 2020 at 11:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.