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

Bri*_*Kim 95 c# asp.net using-statement

在下面的示例中,如果在using语句中引发异常,则连接是否会关闭并处理?

using (var conn = new SqlConnection("..."))
{
    conn.Open();
    // stuff happens here and exception is thrown...
}
Run Code Online (Sandbox Code Playgroud)

我知道下面这段代码会确保它确实如此,但我很好奇使用声明是如何做到的.

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();
}
Run Code Online (Sandbox Code Playgroud)

有关:

抛出异常时,确保SQL连接关闭的正确方法是什么?

Jef*_*tes 105

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

也可以看看:

  • 只是指出连接类,如果你反射它们,你会看到Dispose()确实在内部调用Close().如果它处于可以的状态. (4认同)
  • [MSDN使用文档](http://msdn.microsoft.com/en-us/library/yh598w02.aspx)也确认了这个答案:_ using语句确保即使在调用方法时发生异常也会调用Dispose物体.您可以通过将对象放在try块中然后在finally块中调用Dispose来实现相同的结果; 实际上,这就是编译器如何翻译using语句._ (3认同)
  • 你是对的,的确如此。但是,我故意没有提及它,因为我不想误导任何人以为这与IDisposable或关联的模式有关。该特定实现调用Close()的事实是实现的细节,而不是模式。 (2认同)

Flo*_*bau 19

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

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

所以答案是肯定的,它会关闭连接

DoStuff()
抛出一个例外.