Reputation: 10201
I have a class that exposes a method used to "register" delegates (these delegates are called as part of a later process). The delegate passed to the method is wrapped in a small object which is then added to a dictionary. The method looks a bit like this:-
public void Add(int id, Func<bool> someDelegate)
{
var wrapper = new MyDelegateWrapper(someDelegate);
_wrappers.Add(id, wrapper); // _wrappers is a Dictionary<>
}
Some time later, I might decide to "de-register" delegates by calling a method like this:-
public void Remove(int id)
{
_wrappers.Remove(id);
}
I'm curious to know whether this code introduces any GC issues. i.e. will it prevent either the "wrapper" object, or the object that created the delegate, from being GC'd? And does it make a difference whether the calling objects pass in an anonymous delegate or one of their own "real" methods?
Upvotes: 0
Views: 1582
Reputation: 14007
The GC collects all object that have no incoming references from objects that are not to be collected. That is achieved by creating an object graph from all references on the stack and in static fields. If an object has an outgoing reference to another object, this does not prevent garbage collection.
When you add a handler to an event, this creates a reference from the object that contains the event to the object that contains the event listener. That does not prevent the object with the event to be collected.
The only exception is when you implement the event in method syntax (i.e. using add
and remove
methods) and create a reference from the listener to the object with the event handler in the add
method. That however would be very unusual.
Upvotes: 1
Reputation: 33139
Delegates are not COM objects. They do not need to implement IDispose
and are garbage-collected when the GC deems appropriate to do so.
So as soon as they are no longer reachable from other .NET objects, they will be marked for collection, and will be collected when the CLR needs to clear space.
Upvotes: 3