Да, 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
. К сожалению, в базовой библиотеке есть некоторые классы, которые do генерируют при определенных обстоятельствах, когда вызывается Dispose
- я смотрю на вас, Справочник по услугам WCF / Клиентский прокси! - и когда это происходит, может быть очень трудно отследить исходное исключение, если Dispose
было вызвано во время размотки стека исключений, поскольку исходное исключение проглатывается в пользу нового исключения, сгенерированного вызовом Dispose
. Это может быть безумно расстраивающим. Или это разочаровывающе сводит с ума? Один из двух. Возможно оба.