none
if(!disposing) - Why do we care? RRS feed

  • Question

  •  

    I was just reading about the the finalize/dispose pattern.  One thing I noticed time and time again is that we should check if the user called dispose() or if the runtime called it.  If the user calls dispose, then we should remove managed and unmanaged references.  That makes sense.  If, however, the runtime calls it, then we shouldn't released managed references.

     

    Taken from MSDN:

     

            // If disposing equals false, the method has been called by the
            // runtime from inside the finalizer and you should not reference
            // other objects. Only unmanaged resources can be disposed.

    Okay....WHY???  I've been looking everywhere for answers.  Is it because other managed objects may have already been released?  If so, we still need to destroy our reference, right? 

     

    Thanks for your time

    Friday, March 14, 2008 1:01 AM

Answers

  • You could if you wanted to, but by this time they are already cleaned up and should be null.  So you dont have to do this.  If you really wanted to (for some odd reason) you still can, nothing is stopping you, but make sure you check if(myObject != null) before doing anything with it.

     

    Friday, March 14, 2008 2:27 AM

All replies

  • Actually you should still dispose unmanaged resources,  managed resources are already taken care of by the system so you shouldnt have to worry about this.  So your references should be gone.  You could always do a check if not null or whatever, but its unnecessary.

     

    Friday, March 14, 2008 2:08 AM
  • Shoot, I just realized I had a typo.  I meant to say "managed" but I accidentally said "unmanaged".  My corrections are in bold. 

    My question still is:  Why can't we release managed resources when the runtime calls dispose()?  What is the big deal?
    Friday, March 14, 2008 2:22 AM
  • You could if you wanted to, but by this time they are already cleaned up and should be null.  So you dont have to do this.  If you really wanted to (for some odd reason) you still can, nothing is stopping you, but make sure you check if(myObject != null) before doing anything with it.

     

    Friday, March 14, 2008 2:27 AM
  • I see, thanks.  I don't really plan on doing anything out of the ordinary, I just wanted to know the internals a little bit.  Thanks a lot!
    Friday, March 14, 2008 3:01 AM
  • A lot of people misunderstand the purpose of the Dispose pattern.  (Not to imply that the thread starter does!)   It is overused and in general can be safely ignored by most objects.  In almost no case is it appropriate to free self-contained references  from within Dispose.

    Dispose should be used to call Dispose() on any contained objects which implement IDisposable, and to release unmanaged resources, and to unsubscribe from events fired from long-lived external objects.  If an object doesn't need to do any of these things, it doesn't need to implement IDisposable.

    The garbage collector derives no benefit from an object removing its own references to contained managed objects.  As long as the root of the object graph is unreferenced, the whole graph will be freed.
    Friday, March 14, 2008 3:23 AM
  • The main reason that you should NOT dispose the managed resources inside a finalizer are race conditions. When you are using server GC you have several independant finalizer threads running. When the finalizer runs you should only cleanup your own object handles you did allocate but nothing else. If you call into some other objects Dispose method then you are doing a multithreaded Dispose that will most likely cause hard to find sporadic run time errors if the other object is beeing finalized by another finalizer thread.
    Last but not least you can take locks inside Dispose when your object is disposed normally. That can cause subtle problems when your process is shutting down and you call Dispose on other methods while your object is finalized.

    http://www.codeproject.com/KB/cs/ManagedApplicationShutdow.aspx

    Yours,
      Alois Kraus

    Saturday, March 15, 2008 7:01 PM