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
MethodInfovsActionthat 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:ButtonLet's say you have another class which subscribes to the event fromButtonlike 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
Subscriber1class. 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
buttoninstance is still alive, the GC will not collectsubscriber1Instance. Why? Because it is rooted: thebuttoninstance is holding a reference to it. This is why we should do this instead:In reality
Subscriber1should 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
Clickevent of thebuttoninstance, then thesubscriberIntanceis 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
buttonholding a hard reference to it. Instead the subscriber should derive fromWeakReferenceand pass that to thebuttonwhen subscribing. Like this:To use the above would be like this:
Now
buttonis a holding a weak reference. Which means whensub1is made null and thebuttonfires the event, thenweakwill check ifsub1is null. If yes, it will then check ifbuttonis still alive. If both are true, then it will unsubscribe. Nowsub1is no longer subscribing tobutton.Clickso GC can collect it.