Does Dispose still get called when exception is thrown inside of a using statement?

在下面的示例中,如果异常位于 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();
}

相关阅读:

< a href = “ https://stackoverflow./questions/141204/What-is-the-pert-way-to-sure-a-SQL-connect-is-close-when-an-eption-is”> 当抛出异常时,确保 SQL 连接关闭的正确方法是什么?

33752 次浏览

Yes, using wraps your code in a try/finally block where the finally portion will call Dispose() if it exists. It won't, however, call Close() directly as it only checks for the IDisposable interface being implemented and hence the Dispose() method.

参见:

This is how reflector decodes the IL generated by your code:

private static void Main(string[] args)
{
SqlConnection conn = new SqlConnection("...");
try
{
conn.Open();
DoStuff();
}
finally
{
if (conn != null)
{
conn.Dispose();
}
}
}


所以答案是肯定的,如果

DoStuff ()
抛出异常,它将关闭连接。

Dispose() doesn't get called in this code.

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();
}
}