Question

There have been number of blogs, SO questions telling you how to know if the object is already disposed. E.g. using IsDisposed property available with some classes.

I want to know:

  • Assuming IsDisposed is returning true, if the object is already disposed, how come we are allowed to call a IsDisposed property on it?
  • If we can access its property, how can we say that object is dead or thrown away or disposed? (Are you not referencing it by calling its property?!)

UPDATE # 1:

I have follow up questions after couple of answers stating that "Disposed does not mean object is dead; it just means that any unnanaged resources it's holding are freed up.":

  • Does that mean that Disposed is not saying that this object is disposed?
  • If the Disposed object itself is not dead, why do we get ObjectDisposedException ? (Does not it mean that this object cannot be used any longer? )
Was it helpful?

Solution

"Disposed" is just shorthand for saying "IDisposable.Dispose" has been called. This is typically (but not exclusively) used to mean that it has released any unmanaged resources it might be holding.

It has nothing to do with garbage collection, and doesn't mean that the object is "dead" or "thrown away".

UPDATE

Does that mean that Disposed is not saying that this object is disposed?

No, it means that it is disposed, i.e. it has released its unmanaged resources.

If the Disposed object itself is not dead, why do we get ObjectDisposedException ? (Does not it mean that this object cannot be used any longer? )

It's up to each Type to determine when to throw an ObjectDisposedException. But typically it is thrown when you try to access a member that needs the unmanaged resource that has been released. It's not generally true that ObjectDisposedException is thrown for every member access after an object is disposed.

To take a simple example, if you have a FileStream that is disposed (i.e. the file is closed):

  • Attempting to call, say, ReadByte will throw an ObjectDisposedException, because you can't read from a file that isn't open.

  • But you can still access the Name property, which gives the name that was passed to the FileStream constructor, and doesn't require access to the unmanaged resource (the underlying file).

OTHER TIPS

The purpose of IDisposable is to explicitly request that the unmanaged resources (and managed resources that implement IDisposable) be destroyed before the parent object is destroyed. This saves resources from a garbage collection perspective.

So, IsDisposed will exist right up until the end of the object's lifetime.

Both the .NET and Java frameworks guarantee that absolutely, positively, and without any exception whatsoever, every object will continue to exist, along with all its fields, as long as any kind of reference to it could possibly be retrieved from anywhere in the universe (i.e. it's "reachable"). If the only reachable references to an object are held in WeakReference objects, the garbage-collector will destroy those references (whereupon there will no longer be any reachable references of any sort, anywhere at all, making the object eligible for collection). Objects which have registered finalizers/destructors are handled by having the system keep a list of all such objects; such objects cannot be destroyed until they are removed from that list.

Objects which implement IDisposable follow the above rule in the same way as any other objects. What makes such objects "special" is that many of them will in some methods (possibly including their constructor) ask other entities to do something on their behalf (to the possible detriment of other entities) until further notice; they will give such notice when other methods (including, but not limited to, Dispose) are called. For example, an object encapsulating a file may ask the operating system for exclusive access to a file, thus locking out anyone else who might want to use it, and might inform the operating system such access is no longer needed when Dispose or Close is called. Generally, objects ask entities to act on their behalf because assistance from those entities is needed to implement their methods (e.g. an object won't be able to perform a "read data from file" operation unless it's been given access to the file in question). Once the outside entities have been told their services are no longer required, methods which would require those services will no longer function correctly.

If a method cannot perform its duties because it has released its resources (told outside entities their services are no longer required) in response to a Dispose call, the only accepted way for it to indicate that fact is via an ObjectDisposedException. Further, in cases where a particular method would sometimes be able to perform its duties without the now-unavailable outside help and sometimes not, it is generally considered better to consistently throw ObjectDisposedException than to throw it intermittently. In cases where a particular method or property would not be expected to actually make use of the outside resources, however, it is generally acceptable for a method to ignore the question of whether those resources are still available, especially if there is any plausible reason why someone might want to use that method or property on a disposed instance (the most obvious example being an IsDisposed property).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top