114

在下面的示例中,如果在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 连接的正确方法是什么?

4

3 回答 3

124

是的,using将您的代码包装在 try/finally 块中,如果存在,该finally部分将在该块中调用。Dispose()但是,它不会Close()直接调用,因为它只检查IDisposable正在实现的接口以及Dispose()方法。

也可以看看:

于 2009-02-05T22:54:11.893 回答
21

这就是反射器如何解码您的代码生成的 IL:

私人静态无效主要(字符串[] args)
{
    SqlConnection conn = new SqlConnection("...");
    尝试
    {
        conn.Open();
        做东西();
    }
    最后
    {
        如果(连接!= null)
        {
            conn.Dispose();
        }
    }
}

所以答案是肯定的,如果

做东西()
抛出异常。

于 2009-02-05T22:58:23.710 回答
-1

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();
    }
}
于 2019-05-08T16:28:05.937 回答