Вызывается ли Dispose все еще, когда исключение выбрасывается внутри оператора using?
В приведенном ниже примере соединение закрывается и удаляется, когда генерируется исключение, если оно находится в инструкции using
?
using (var conn = new SqlConnection("..."))
{
conn.Open();
// stuff happens here and exception is thrown...
}
Я знаю, что этот код ниже будет убедиться, что это так, но мне любопытно, как это делает оператор.
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 закрывается при вызове исключения?
Ответы
Ответ 1
Да, using
обертывает ваш код в блок try/finally, где часть finally
вызывает Dispose()
, если она существует. Однако он не будет называть Close()
напрямую, поскольку он проверяет только реализованный интерфейс IDisposable
и, следовательно, метод Dispose()
.
См. также:
Ответ 2
Так рефлектор декодирует IL, сгенерированный вашим кодом:
private static void Main(string[] args)
{
SqlConnection conn = new SqlConnection("...");
try
{
conn.Open();
DoStuff();
}
finally
{
if (conn != null)
{
conn.Dispose();
}
}
}
Итак, ответ да, он закроет соединение, если
DoStuff()
выдает исключение.
Ответ 3
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();
}
}