Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a using block guarantee that the object will not be disposed until the end of the block?

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?

like image 803
Shaul Behr Avatar asked Dec 15 '22 08:12

Shaul Behr


2 Answers

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.

like image 106
p.s.w.g Avatar answered May 15 '23 06:05

p.s.w.g


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.

like image 24
Mike Zboray Avatar answered May 15 '23 07:05

Mike Zboray