在using语句中抛出异常时,是否仍会调用Dispose?

时间:2009-02-05 22:51:42

标签: c# asp.net 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();
}
相关: What is the proper way to ensure a SQL connection is closed when an exception is thrown?

3 个答案:

答案 0 :(得分:94)

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

另见:

答案 1 :(得分:18)

这是反射器解码代码生成的IL的方式:

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

所以答案是肯定的,如果

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

答案 2 :(得分:-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();
    }
}
相关问题