Reputation: 11254
I'm looking for a solution avoiding memory leaks when using events (which may occur if the listener is never removed from the event source. I found this code project article describing a WeakEvent
class like this:
sealed class EventWrapper
{
SourceObject eventSource;
WeakReference wr;
public EventWrapper(SourceObject eventSource,
ListenerObject obj) {
this.eventSource = eventSource;
this.wr = new WeakReference(obj);
eventSource.Event += OnEvent;
}
void OnEvent(object sender, EventArgs e)
{
ListenerObject obj = (ListenerObject)wr.Target;
if (obj != null)
obj.OnEvent(sender, e);
else
Deregister();
}
public void Deregister()
{
eventSource.Event -= OnEvent;
}
}
As far a I understood the listener object is wrapped in a WeakReference
, which is not considered as a reference to the event listener from the Garbage Collectors' point of view.
My question: When using this pattern, is it possible that the Garbage Collector deletes ListenerObject obj
though no event was fired by the event source beforehand? In that case, the whole pattern becomes indeterministic since the fired event is not forwarded to the ListenerObject
, because the Garbage Collector deleted it (because there is only a WeakReference
pointing to it). If this is correct why should I use a pattern like this anyway?
Thx
Upvotes: 2
Views: 87
Reputation: 42245
Yes, if the WeakReference
is the only thing which holds a reference to ListenerObject
, then ListenerObject
can be GC'd at any point.
You would use a pattern like this if your EventWrapper
class is not the only thing which has a reference to ListenerObject
, but your EventWrapper
doesn't know when that other thing is going to release its reference to ListenerObject
.
For example, ListenerObject
might be a UI control which appears on a screen, and the EventWrapper
might be owned by a singleton service. The UI control will stay alive as long as that screen is shown, but will be released when the user changes the screen. The service might not know when that happens. Using a weak event pattern means that you don't accidentally end up with a memory leak in this case.
Note, if you do want to implement the weak event pattern, use a WeakEventManager
as detailed in this article.
Upvotes: 2