Search code examples
c#weak-references

Can event listener of WeakEvent be deleted by garbage collection any time?


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


Solution

  • 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.