I know a using
block ensures that the IDisposable
object being "used" will be disposed at the end of the block - but does it guarantee that the object will not be disposed before then?
In other words, if I have:
using (new DisposableObject()) {
// blah blah
}
can I be sure that the DisposableObject
will not be disposed until the end of the block, or might the garbage collector detect that I have no handle to it inside the block, and dispose it right away?
No it doesn't. There's nothing stopping you from doing:
using(var myObject = new DisposableObject())
{
myObject.Dispose();
}
What exactly will happen in this case depends on the semantics of DisposableObject
. It may throw an exception, or it may be perfectly happy with Dispose
being called twice.
It should be noted that object disposal and garbage collection are completely different concepts. Just because an object is disposed doesn't mean it will be garbage collected and just because an object has been garbage collected doesn't mean it will be disposed.
An object may be garbage collected once all references to the object are destroyed or are unreachable. That can't happen while the code is running inside the using
-block, because the block itself has a reference to the object.
Your object will only be disposed once and will not be GC'd before the end of the using block.
The specification guarantees that when you have using (expression) statement
and the type of expression is a nullable type (call it ResourceType
) then it is expanded into:
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
Dispose
will be called once at the end of the block and there is a local generated that keeps a reference to your disposable object. The local prevents the object from being GC'd before the end of the using block.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With