I am looking at a mediator prototype here https://joshsmithonwpf.wordpress.com/2009/04/06/a-mediator-prototype-for-wpf-apps/.
The author indicates that "My first thought was to store a reference to the Action in a WeakReference. Since the Garbage Collector will throw away objects that are referenced only by WeakReference objects, it would seem that this would do the trick. Unfortunately, it’s not that simple. The problem with that approach is that the GC will throw away the Action instance because it is only being referenced by a WeakReference!"
My question is instead of using "a reference to Action", why "a reference to MethodInfo" do the trick? I assume the methodinfo should be collected as well.
Thanks in advance.
No, it is not really
MethodInfo
vsAction
that does the trick. It is something else but I have to admit, that article is not very well written and can be confusing. Let me try and explain.Events and GC
Let's say you have a class with an event called
Click
. The class is:Button
Let's say you have another class which subscribes to the event fromButton
like this:Now how does the button class know who to notify when the button is clicked? Well, it keeps a reference to all those classes that have subscribed. So in the case above it will hold a reference to an instance of the
Subscriber1
class. Whenever, the button is clicked it will notify instance ofSubscriber1
. So what will happen if we do this:What will happen is that if the
button
instance is still alive, the GC will not collectsubscriber1Instance
. Why? Because it is rooted: thebutton
instance is holding a reference to it. This is why we should do this instead:In reality
Subscriber1
should implement IDisposable and do the unsubscribing there but the point of this answer is not that. So I am keeping it simple so we do not lose focus.When we unsubscribe from the
Click
event of thebutton
instance, then thesubscriberIntance
is no longer rooted and it can be cleaned up by the GC.So what is the article doing?
In that article, the authors are trying to solve this issue of developers forgetting to unsubscribe and thus leading to memory leak issues. Note this is one way: only if the publisher outlives the subscriber, it will keep the subscriber alive, not the other way around. So if the publisher is ready for GC, the subscriber will not be able to keep it alive.
Basically what the authors are saying is that the subscriber should not subscribe to the event directly so it does not result in the
button
holding a hard reference to it. Instead the subscriber should derive fromWeakReference
and pass that to thebutton
when subscribing. Like this:To use the above would be like this:
Now
button
is a holding a weak reference. Which means whensub1
is made null and thebutton
fires the event, thenweak
will check ifsub1
is null. If yes, it will then check ifbutton
is still alive. If both are true, then it will unsubscribe. Nowsub1
is no longer subscribing tobutton.Click
so GC can collect it.