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

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

Brian Kim asked 2019-09-11T10:41:01Z
2个解决方案
94 votes

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

也可以看看:

  • 拦截IDisposable.Dispose中的异常
  • 抛出异常时,确保SQL连接关闭的正确方法是什么?
  • C#“使用”语法
  • C#USING关键字 - 何时何地不使用它?
  • '使用'声明vs'尝试终于'
  • 什么是C#Using块,我为什么要使用它?
  • 一次性使用模式
  • 结束使用关闭打开的SQL连接
Jeff Yates answered 2019-09-11T10:42:11Z
18 votes

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

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

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

DoStuff()
抛出一个例外。

Florin Sabau answered 2019-09-11T10:42:49Z
translate from https://stackoverflow.com:/questions/518352/does-dispose-still-get-called-when-exception-is-thrown-inside-of-a-using-stateme