Posted By: ilya | Jan 5th, 2006 @ 7:56 AM
page 1 of 1
Comments: 17 | Views: 8369

If I create a BaseObject and I declare some events inside of that object that people can subscribe to and then I call a dispose method, will this object be disposed? or do I have to unhook the events first and then the object will be disposed?

If I have to dispose the events first what is the best way of unhooking the events from the BaseObject and make sure that all inheriting classes that have events will also unhook their events if they have custom events?

Thanks,

Ilya

Calling a dispose method does not release the object to the garbage collector, regardless of what you do inside that object.

Yes it is recommended to unhook your events in your dispose.  Just set your event to null in your base class dispose method.  Make sure you use the Dispose pattern.

 

Later

sprayer

Follow the Finalize & Dispose pattern

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconFinalizeDispose.asp

At the URL there is an example of a implementing Dispose in a Base-Derived class.

Tip:
If your are using VS2005 you can create a Dispose Snippet to speed up the process and do most of the work for you.

Later
sprayer

You dont need to explicitly remove each event handler.

Here is an example of the Dispose & Event pattern.


// Design pattern for a base class.
public class Base: IDisposable
{
   public event EventHandler BaseEvent;
  
   protected virtual void OnBaseEvent()
   {
      if (BaseEvent != null)
      {
         BaseEvent(this, EventArgs.Empty);
      }
   }
     
   //Implement IDisposable.
   public void Dispose()
   {
     Dispose(true);
      GC.SuppressFinalize(this);
   }

   protected virtual void Dispose(bool disposing)
   {
      if (disposing)
      {
         // Free other state (managed objects).
         if (BaseEvent != null)
         {
            BaseEvent = null;
         }
      }
      // Free your own state (unmanaged objects).
      // Set large fields to null.
   }

   // Use C# destructor syntax for finalization code.
   ~Base()
   {
      // Simply call Dispose(false).
      Dispose (false);
   }
  
// Design pattern for a derived class.
public class Derived: Base
{  
   public event EventHandler DerivedEvent;
  
   protected virtual void OnDerivedEvent()
   {
      if (DerivedEvent != null)
      {
         DerivedEvent(this, EventArgs.Empty);
      }
   }
  
   protected override void Dispose(bool disposing)
   {
      if (disposing)
      {
         // Release managed resources.
         if(DerivedEvent != null)
         {
            DerivedEvent = null;
         }
      }
      // Release unmanaged resources.
      // Set large fields to null.
      // Call Dispose on your base class.
      base.Dispose(disposing);
   }
   // The derived class does not have a Finalize method
   // or a Dispose method with parameters because it inherits
   // them from the base class.
}

ilya wrote:

If you read what i wrote above "I don't want to explicitly specify/set the events to null for every object"
Reason being is that if I have a lot of objects that I will create that will inherit from the BaseObject I don't want to specifically set the Event Fields to null. Especially during the call to the Dispose method I want to be able to call this "ReleaseEvents" method to unhook all the event starting from the BaseObject and all the way up the Inheritance chain.



1) There is no reason for you to have to null out your events.  The subscribers will not know that your object has disappeared nor will they care.

2) If you do decide to set the events to null, you should simply clear the events that are explicitly created by the child object in the code.  Then call the parent dispose function.  This is called inheritance.

3) See #1.  You are wasting your time worrying about this.
ilya wrote:

1) Sometimes I will want to know if an object is being deleted/disposed because I am listening for that also...


on a slippery slope with that kinda requirement in the managed world... i would just use VC++.NET 2005 and delete the managed object, makes me feel better, but even then you wouldnt put a mortgage on it not being around.Tongue Out
Good work ilya! You certainly solved my problem.
I'm interested in how this code works.  Do you mind adding some more comments and/or add a dummy class that inherits from your BaseObject class.

Will this remove user created events (not just the default events that are available with the control)?


Thanks,

- Paul

I'm still interested in learning more about how this code works.  Can you 1) provide a sample application and 2) explain how this could be used to handle delegates.  Does GetEvents() return an instance's delegates as well?

Thanks,

Paul

Is any of that strictly necessary?

Wouldn't the garbage collector destroy the object regardless of whether anything was listening for the events? I can't see why the GC wouldn't destroy your object - unless a subscriber holds a reference to the object to which it is subscribed. Which would be stupid - and against the whole point of events in the first place.

In which case what do you gain? I can't see any benefit - and if you want to know when an object has been disposed of, then you could just add an event to tell you. In fact how would this help in that case either?