Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MSDN Dispose() example erroneous? (when to set managed references to null)

Tags:

c#

MSDN's example pattern for implementing a Dispose() method depicts setting the reference to a disposed managed resource to null (_resource = null), but does so outside the if (disposing) block:

protected virtual void Dispose(bool disposing)
{
    // If you need thread safety, use a lock around these 
    // operations, as well as in your methods that use the resource.
    if (!_disposed)
    {
        if (disposing) {
            if (_resource != null)
                _resource.Dispose();
                Console.WriteLine("Object disposed.");
        }

        // Indicate that the instance has been disposed.
        _resource = null;
        _disposed = true;   
    }
}

Shouldn't _resource = null be placed inside this code block? If a call to Dispose(false) is made then _resource will be null and unable to be subsequently disposed! ??

Of course, Dispose(false) is only called (in practice) by the runtime during finalization. But if _resource wasn't previously disposed, what is the need to set it to null at this point when the object (including the _resource member field) is about to be garbage collected?


[end of original question]

Follow up:

After much reading, it appears setting the reference to null is not necessary, but may be a good idea for "heavy" member objects if you have reason to believe the containing class (the one being disposed) might not be garbage collected soon.

Know that object disposal is no assurance that the object has been "released" by consuming code. The disposed object might be kept around (in a collection or otherwise) for various purposes, or just in error. I can imagine an application that uses objects from a collection then disposes of them, but keeps them in the collection for a later process to perform removal and log final state (or something like that... who knows...)

Conclusions:

  1. Setting references to "heavy" member objects to null releases them for garbage collection even if the disposed object is not released.
  2. It is overkill to clear references for all objects.
  3. Hence, placement of the _resource = null statement (the original question) is not important for two reasons: (A) Using it at all is only something to think about after reading the above; (B) In the MSDN example, it executes for both Dispose(true) and Dispose(false), but the latter only occurs when the object is finalized and just about to be garbage collected anyway!

Thus, my preference will be to place _resource = null inside the most inner if block:

if (disposing) {
    if (_resource != null) {
        _resource.Dispose();
        _resource = null;
    }
}

This keeps all the _resource code together. Further thoughts, anyone?

More reading:

  • In the Dispose(bool) method implementation, Shouldn't one set members to null?
  • Do you need to dispose of objects and set them to null?
  • http://www.codeproject.com/KB/dotnet/idisposable.aspx (Very good, and long!)
like image 985
Kevin P. Rice Avatar asked Jul 20 '11 04:07

Kevin P. Rice


People also ask

Does Dispose set object to NULL?

When an object implements IDisposable you should call Dispose (or Close , in some cases, that will call Dispose for you). You normally do not have to set objects to null , because the GC will know that an object will not be used anymore.

What is Dispose () in C#?

In the context of C#, dispose is an object method invoked to execute code required for memory cleanup and release and reset unmanaged resources, such as file handles and database connections.

Who will call Dispose method C#?

Before the GC deallocates the memory, the framework calls the object's Finalize() method, but developers are responsible for calling the Dispose() method. The two methods are not equivalent.

How check object is disposed or not in C#?

The object must not throw an exception if its Dispose method is called multiple times. Instance methods other than Dispose can throw an ObjectDisposedException when resources are already disposed." msdn.microsoft.com/en-us/library/… @HansPassant: If an object implements IDisposable , one can call (IDisposable.


1 Answers

Setting it to null is removing the reference or pointer to the location in the heap. This lets the GC go through and remove anything that has no references to it without it having to do much guesswork. _resource would be some internal use object that needs to have its references cleaned up so lets say you have a Socket internal to your close you would close/dispose of that socket or any other persistent resource. Once it's disposed you set it to null and remove all references (should remove all references) so that GC can do it's job fine. The 2nd half of my answer is an example so it kind of repeats some things but I hope you get the idea.

Setting it to null twice isn't a big deal as there's no effect. Disposing should be true at the time of cleaning up any resources and it's only false once it is (as you said) about to be garbage collected anyway.

like image 103
Jesus Ramos Avatar answered Oct 07 '22 22:10

Jesus Ramos