This was a telephone interview question I had: Is there a time when Dispose will not be called on an object who's scope is declared by a using block?
My answer was no - even if an exception happens during the using block, Dispose will still be called.
The interviewer disagreed and said if using
is wrapped in a try
-catch
block then Dispose will not be called by the time you enter the catch block.
This goes contrary to my understanding of the construct, and I haven't been able to find anything that backs up the interviewers point of view. Is he correct or might I have misunderstood the question?
Four things that will cause Dispose to not be called in a using block:
StackOverflowException
,AccessViolationException
and possibly others.This produced :
So I agree with you and not with the smarty interviewer...
Bizarrely I read about a circumstance where Dispose won't get called in a using block just this morning. Checkout this blog on MSDN. It's around using Dispose with IEnumerable and the yield keyword, when you don't iterate the entire collection.
Unfortunately this doesn't deal with the exception case, honestly I'm not sure about that one. I would have expected it to be done but maybe it's worth checking with a quick bit of code?
Yes there is a case when dispose won't be called... you are over thinking it. The case is when the variable in the using block is
null
will not throw an exception but would if dispose was called in every case. The specific case that your interviewer mentioned is wrong though.
The
using
block gets turned by the compiler into atry
/finally
block of its own, within the existingtry
block.For example:
becomes
The compiler won't rearrange things. So it happens like this:
using
block'stry
partusing
block'stry
part, and enters itsfinally
partfinally
blocktry
try
and goes into the exception handlerPoint being, the inner
finally
block always runs before the outercatch
, because the exception doesn't propagate til thefinally
block finishes.The only normal case where this won't happen, is in a generator (excuse me, "iterator"). An iterator gets turned into a semi-complicated state machine, and
finally
blocks are not guaranteed to run if it becomes unreachable after ayield return
(but before it has been disposed).