开发者

Help me understand Dispose() implementation code from MSDN

the following code is from MSDN: Idisposable pattern

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;   
        }
    }

why the following statement:

 _resource = null;  
_disposed = true; 

are not enclosed by if (disposing) statement block?

for me i would probably write like this:

if (disposin开发者_开发知识库g) {
       if (_resource != null) {
            _resource.Dispose();
            _resource = null;
            _disposed = true;
           }
         Console.WriteLine("Object disposed.");
   }

anything wrong with my version?


The pattern outlined by the MSDN is the only correct way to implement IDisposable because it takes finalization into account. You need to look closely at the IDisposable implementation:

public void Dispose() 
{
    Dispose(true);

    // Use SupressFinalize in case a subclass
    // of this type implements a finalizer.
    GC.SuppressFinalize(this);      
}

This calls your dispose method, indicating it's a real dispose and supresses further finalization.

It's not safe to call out to any other object during finalization, so that's why you want to set:

 _resource = null;  
_disposed = true; 

to prevent any further mishappenings.

Here's a good info on finalization and IDisposable on MSDN.


After the call to Dispose() the resource should always be marked as disposed because otherwise you could run into problems. So even if _resource is null, you need to mark it as disposed.

Running

_resource = null;

doesn't hurt even if the resource was null at the first place.


Yes ;)

Ok, the _resource = null - has IMHO to go in as you said. The sample code is sloppy here, sorry ;) I also prefer it your way.

_disposed = true, though, is INDEPENDENT on the existence if _resource. It should ALSO be set if the _resource pointer has not been initialized to start with, so it should go DIRECTLY above the Console.WriteLine. Imagine a situation where the _resource is a file handler, which is opened during a method call in the classs - there may be scenarios where the class is created, but the file handler not, and in this case dispose has to also function.

if (disposing) {
if (_resource != null) {
_resource.Dispose();
_resource = null;
}
_disposed = true;
Console.WriteLine("Object disposed.");
}

is how I would write it.


The Dispose(bool) function is usually called both from Dispose() and from the Finalizer (named ~Class in C#). When called by the finalizer, garbage collection is already underway, and the order of garbage collection between different objects is not defined. The garbage collector might very well have destroyed _resource already, so it's only when Dispose(bool) is called from Dispose() that we want to destroy "child resources" (This is true for managed resources, unmanaged resources should always be freed)


The placement of the 2 lines in question is correct in the MSDN pattern

The reason is that in a correct implementation, as provided on my blog referenced below, the overloaded version of Dispose(bool) passes a value of false in the call from the Finalizer. Note that you should only implement a Finalizer if you truly need one. That being said, the placement of these lines should not vary based on whether or not you implement a Finalizer.

I've written an improved version of the IDisposable pattern on my blog - How do you properly implement the IDisposable pattern?. You will find that my provided implementation of this pattern is slightly different than that which is posted on MSDN. IMHO, it isn't sufficient. You have to agree that a large number of samples and examples posted on MSDN are "hacky" and don't do things the way that they should be done in the "real world".

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜