Is there a simple way to iterate all over the handlers subscribed to a given event? My problem is that clients subscribe but forget to unsubscribe so a memory leak happens. I need a way for an object to disconnect all the handlers of its events in the Dispose method so a leak would not happen - at least not开发者_StackOverflow中文版 because of events.
Set null to your event: MyEvent = null;
But it is really better to make clients unsubscribing from your event.
An alternative approach is to use so-called "weak delegate" pattern. When you use this technique, the event references clients only using WeakReference
which doesn't keep them in memory. The clients will be garbage collected when they are no longer referenced from other part of the application (and the handler can be also unregistered automatically when the client is collected).
This is usually used to solve the problem with clients "forgetting" to unsubscribe from a .NET event, so it sounds like this might be well suited for your problem.
- Dusing Campbell has a nice article about weak delegates.
- I also liked this overview at CodeProject, which discusses most of the scenarios.
- Weak Events are also used in WPF, but this approach seems a bit complicated (to me).
Memory leak happens only if another object (listener) dies before your object (event source). In this case, event source still keeps the reference to listener, which prevents listener to be collected. When event source dies, unsubscribed listener may be collected as well.
If event source dies before listener, this does not prevent listener to be collected later, when all other references to it are set to null.
This means, event source Dispose method is not correct place to solve this problem. It may be solved only in a listener code. Simply talking, you cannot do anything, except asking your clients to write clean code.
At the time of writing, the most accurate answer is the least popular.
You can nullify the event handler but this would be zapped anyway after its owner is zapped - its not wrong to be super tidy, but like Alex says, it's not where the issue is.
Adi's source class will allow listening objects to be collected when it itself is collected, there is no doubt. So the problem is that Adi's source object is being kept open, possibly from some long chain of references in his customer's code.
The following blog post also looks at a solution that Adi is decribing and explains why it's unnecessary.
http://weblogs.sqlteam.com/mladenp/archive/2007/10/24/C-Care-about-Event-Memory-Leaks-with-Delegate.GetInvocationList.aspx
精彩评论