Да, 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
вызовом. Это может быть безумно неприятным. Или это ужасно сводит с ума? Один из двух. Возможно оба.