Dispose по-прежнему вызывается, когда в операторе using генерируется исключение?
В приведенном ниже примере, будет ли соединение закрываться и удаляться при возникновении исключения, если оно находится в пределах using
заявление?
using (var conn = new SqlConnection("..."))
{
conn.Open();
// stuff happens here and exception is thrown...
}
Я знаю, что приведенный ниже код будет гарантировать, что он делает, но мне любопытно, как это делает оператор using.
var conn;
try
{
conn = new SqlConnection("...");
conn.Open();
// stuff happens here and exception is thrown...
}
// catch it or let it bubble up
finally
{
conn.Dispose();
}
Связанные с:
Как правильно обеспечить закрытие соединения SQL при возникновении исключения?2 ответа
Решение
Да, using
оборачивает ваш код в блок try/finally, где finally
часть позвонит Dispose()
если он существует. Это, однако, не вызовет Close()
непосредственно, поскольку он проверяет только IDisposable
интерфейс реализуется и, следовательно, Dispose()
метод.
Смотрите также:
- Перехват исключения внутри IDisposable.Dispose
- Как правильно обеспечить закрытие соединения SQL при возникновении исключения?
- C# "Использование" Синтаксис
- Ключевое слово C# USING - когда и когда его не использовать?
- "используя" заявление против "попробуй наконец"
- Что такое блок C# Using и зачем его использовать?
- Одноразовые с использованием шаблона
- Завершает ли использование закрытие открытого соединения SQL
Вот как отражатель декодирует IL, сгенерированный вашим кодом:
закрытая статическая пустота Main(string[] args) { SqlConnection conn = new SqlConnection("..."); пытаться { conn.Open(); DoStuff(); } в конце концов { if (conn!= null) { conn.Dispose(); } } }
Так что ответ да, он закроет соединение, если
DoStuff ()бросает исключение.
Dispose() не вызывается в этом коде.
class Program {
static void Main(string[] args) {
using (SomeClass sc = new SomeClass())
{
string str = sc.DoSomething();
sc.BlowUp();
}
}
}
public class SomeClass : IDisposable {
private System.IO.StreamWriter wtr = null;
public SomeClass() {
string path = System.IO.Path.GetTempFileName();
this.wtr = new System.IO.StreamWriter(path);
this.wtr.WriteLine("SomeClass()");
}
public void BlowUp() {
this.wtr.WriteLine("BlowUp()");
throw new Exception("An exception was thrown.");
}
public string DoSomething() {
this.wtr.WriteLine("DoSomething()");
return "Did something.";
}
public void Dispose() {
this.wtr.WriteLine("Dispose()");
this.wtr.Dispose();
}
}