Landin Martens
Landin Martens

Reputation: 3333

If an instance is not referenced but its callback is, will the instance be garbage collected?

I hope I can explain this properly.

If have a class called EventHandler and it is created via the 'new' keyword within the scope of a single method call (example below), my understanding is that once the method ends, the instance of EventHandler should be marked for garbage collection as it has now fallen out of scope.

Now what would happened if within the method call that created this new EventHandler instance, a method of EventHandler is passed as a callback Action to another method but the callback does not fire until long after the EventHandler is out of scope?

From my understanding, if the above situation happened, the callback would throw an exception as its instance is no longer alive as it had been garbage collected. Am I correct or is the fact that a method of the EventHandler is used as a callback this will cause the EventHandler to not be garbage collected until that reference to that callback is no more, even though nothing is directly referencing that instance to EventHandler?

Example:

Public void SomeMethod()
{
    var eventHandler = new EventHandler();

    //The callback below does not fire until AFTER 'SomeMethod' has ended
    RegisterCallBackForSomeEventMethod(eventHandler.SomeMethodToUseAsACallBack);

}   //SomeMethod has ended, 'eventHandler' has now fallen out of scope

Upvotes: 0

Views: 74

Answers (1)

i3arnon
i3arnon

Reputation: 116558

The instance will not be garbage collected.

There's no special treatment in place here. This instance will not be collected because the delegate keeps a reference to it in the Target property. As long as you keep a reference to the delegate you're sending to RegisterCallBackForSomeEventMethod you are actually keeping a reference to the EventHandler instance as well.

You can easily see that in this simple example:

private static void Main()
{
    var eventHandler = new EventHandler();
    RegisterCallBackForSomeEventMethod(eventHandler.SomeMethodToUseAsACallBack);
}

private static void RegisterCallBackForSomeEventMethod(Action action)
{
    Console.WriteLine(action.Target.GetType());
}

Output:

Sandbox.EventHandler

Upvotes: 4

Related Questions