If object A listens to an event from object B, object B will keep object A alive. Is there a standard implementation of weak events that would prevent this? I know WPF has some mechanism but I am looking for something not tied to WPF. I am guessing the solution should use weak references somewhere.
相关问题
- Generic Generics in Managed C++
- How to Debug/Register a Permanent WMI Event Which
- C# GC not freeing memory [duplicate]
- 'System.Threading.ThreadAbortException' in
- Bulk update SQL Server C#
Be careful when using weak events implementations. Weak events appear to remove from the subscriber the responsibility of unsubscribing from the event (or message). In that case event handlers may be invoked even after the subscriber "goes out of scope". Take a subscriber that does not explicitly unsubscribe and that becomes garbage collectable but is not yet garbage collected. The weak event manager will not be able to detect that state and because of that it will still call the event handler of that subscriber. This can lead to all kind of unexpected side effects.
See more details at The Weak Event Pattern is Dangerous.
See this source code that illustrates this issue using the MvvMCross messaging plugin as a weak event manager.
I repackaged Dustin Campbell's implementation to make it a little easier to extend it for different event types when generic handlers aren't used. I figure it may be of some use to someone.
Credits:
Mr. Campbell's original implementation
A very handy delegate cast function by Ed Ball, link can be found in source
The handler and a couple of overloads, EventHander<E> and PropertyChangedEventHandler:
Unit tests:
Dustin Campbell from the DidItWith.NET blog examines several of the failed attempts to create weak event handlers, then goes on to show a valid, working, lightweight implementation: Solving the Problem With Weak Event Handlers.
Ideally, though, Microsoft would introduce the concept into the language itself. Something like:
If you feel this feature is important to you, please vote for it here.
Dustin Campbell's approach is already excellent. The only thing left, save a solution integrated into .NET, is a really simple way to create really generic weak event handlers:
http://puremsil.wordpress.com/2010/05/03/generic-weak-event-handlers/
An important detail:
Dustin's implementation eliminates a strong reference introduced by the event handler, but it may introduce a new memory leak (at least when not paying enough attention to).
Since the unregister callback is not treated as a weak event handler it may contain a strong reference to some object. It depends on whether you declare the unregister callback in the Event subscriber class or not.
If not doing so, the callback will be associated with a reference to the enclosing class instance. Here is an example of what I am refering to: After declaring the unregister callback it will contain a reference to the Program class instance:
Dustin's implementation only works with EventHandler delegates. If you head over to CodePlex there's a project called Sharp Observation in which the author has built a very good weak delegate provider. It's implemented in MSIL and is considerably faster and more flexible.
... which, until Microsoft implement weak events natively, will have to do.