Да, Dispose
будет называться. Он вызывается, как только выполнение выходит за пределы блока using
, независимо от того, какие средства потребовались для выхода из блока, будь то конец выполнения блока, оператор return
или исключение.
Как правильно указывает @Noldorin, использование блока using
в коде компилируется в _5 _ / _ 6_, причем 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 / Прокси-сервер клиента! - и когда это происходит, может быть очень сложно отследить исходное исключение, если Dispose
был вызван во время раскрутки стека исключений, поскольку исходное исключение проглатывается в пользу нового исключения, сгенерированного вызовом Dispose
. Это может раздражать до безумия. Или это ужасно сводит с ума? Один из двух. Возможно оба.
person
Randolpho
schedule
14.07.2010