Да, Disposeназовут. Он вызывается, как только выполнение покидает область действия usingблока, независимо от того, какие средства потребовались для выхода из блока, будь то конец выполнения блока, returnинструкция или исключение.
Как правильно указывает @Noldorin, использование usingблока в коде компилируется в try/ finallyс вызовом Disposeв finallyблоке. Например, следующий код:
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
фактически становится:
MemoryStream ms = new MemoryStream();
try
{
// code
return 0;
}
finally
{
ms.Dispose();
}
Таким образом, поскольку finallyон гарантированно выполняется после tryзавершения выполнения блока, независимо от его пути выполнения, Disposeон гарантированно будет вызван, несмотря ни на что.
Дополнительные сведения см. В этой статье MSDN .
Дополнение:
небольшая оговорка, которую следует добавить: поскольку Disposeвызывается гарантированно, почти всегда полезно убедиться, что Disposeпри реализации никогда не будет генерироваться исключение IDisposable. К сожалению, есть некоторые классы в библиотеке ядра , которые делают бросок в определенных обстоятельствах , когда Disposeназываются - я смотрю на вас, WCF Service Reference / Client Proxy! - и когда это происходит, может быть очень сложно отследить исходное исключение, если оно Disposeбыло вызвано во время раскрутки стека исключений, поскольку исходное исключение поглощается в пользу нового исключения, сгенерированного Disposeвызовом. Это может быть безумно неприятным. Или это ужасно сводит с ума? Один из двух. Возможно оба.