Event Handling

JEHMayo

Newcomer
Joined
Aug 15, 2003
Messages
10
Location
Chattanooga, Tennessee
Assume you instantiate a new object that can raise an event and, then, add an event handler. In order to clean up, after all references to that object have been removed (set to Nothing), do you have to explicitly execute a RemoveHandler command as part of the cleanup or will that be taken care of somehow in the garbage collection process without any explicit programming?
 
No, the method that you originally subscribed to the event with will have gone out of scope. When the class fires the event it should always check the underlying delegate to make sure that it is not null.
 
Event Handler

Thanks for the quick reply. However, I don't think I expressed my question very well -- it's about clean up. I'm destroying (removing all references to) an object that raises events. Event handlers have been added along the way.

Since the object that raises events has been dereferenced, it will not raise its events anymore. My question is whether, to complete clean up, do I need to explicitly execute RemoveHandler for each handler that had been added for that specific instance of the object before completing its eligibility for destruction by removing all references to the instance of the object?
 
The reference to the "client" object's method (the method that is fired when the event is raised) is living in the object that has the event. Once this object is destroyed, the underlying method reference is also destroyed.
 
This might clarify it:
C#:
static void Main(string[] args)
{
    MyClass m = new MyClass();
    m.MyEvent += new MyDelegate(m_MyEvent);

    // "m_MyEvent" will fire when the event is raised

    m = null;

    // "m_MyEvent" is no longer subscribed to any events and will *never* fire

    Console.WriteLine("Done...");
    Console.ReadLine();
}

static void m_MyEvent()
{
    
}
 
Suppose an object X subscribes to an event of object Y. The following chart shows how the references affect garbage collection. The important thing to understand is how events are stored. When X handles an event from Y, X does not store a reference to the event in Y, but rather Y stores a reference to the handler in X. This means that when X handles events from Y we don't have references from X to Y, but exactly the opposite.

After looking at the chart, one might think something like, "What if a .Net method is used as a callback for Windows or an unmanaged DLL? Then wouldn't the object still be active even though no .Net objects reference it? Couldn't it raise events even though it is eligible for garbage collection?" The answer is that when we pass a delegate to an unmanaged DLL, the .Net runtime sets up a thunk to marshal data between managed and unmanaged code, and this thunk maintains a reference to the object in question, "rooting" it and preventing it from being garbage collected.
 

Attachments

Back
Top