我需要使用关键字 'using' 来关闭 SQL Server 连接吗?

10

我经常发现这个问题的结果相互矛盾。让我们看看这个运行SQL查询的C#代码:

using (SqlConnection cn = new SqlConnection(strConnectString))
{
    cn.Open();

    using (SqlCommand cmd = new SqlCommand(strSQL, cn))
    {
        cmd.ExecuteNonQuery();
    }

    //Do I need to call?
    cn.Close();
}

我需要调用最后的cn.Close()吗?我之所以问这个问题是因为在一个高并发的Web应用程序中,我会耗尽连接池中的连接。

3个回答

12

这里使用的 using 关键字:

using (SqlConnection cn = new SqlConnection(strConnectString))
{
    // Stuff
}

是缩写形式,意为:

SqlConnection cn = null;
try
{
    cn = new SqlConnection(strConnectString);
    // Stuff
}
finally
{
    if (cn != null) cn.Dispose();
}
cn.Dispose()会在using作用域结束时立即被调用,这将立即关闭连接(因为SqlConnection.Dispose()就是这样做的)。请注意,这与垃圾回收不同。在.NET中,GC是非确定性的,这正是为什么引入了接口和Dispose Pattern的原因。IDisposable允许及时、确定性地释放昂贵的资源。

1

使用Using语句时,您不需要关闭连接。

Scott Hanselman在这里解释了为什么Using语句比插眼和SqlConnection重构示例更好。

在一个高并发的Web应用程序中,我用光了连接池中的连接。

确保您使用相同的连接字符串,这样SQL将使用连接池。

连接是立即关闭还是等到垃圾回收器处理它时才关闭?

编辑:

Dispose模式用于提供资源的确定性销毁。由于.NET运行时垃圾回收器是非确定性的(这意味着您永远无法确定运行时何时收集旧对象并调用它们的终结器)。因此,当您正确实现Dispose模式时,您提供了资源的确定性释放,在消费者粗心地不处理对象的情况下,终结器将清理该对象。


谢谢。问题是 - 连接是立即关闭还是在垃圾收集器到达时关闭?因为这在我的情况下有所不同。 - c00000fd
“确保您使用相同的连接字符串”--这是什么意思?将SqlConnection cn定义为静态变量? - c00000fd
1
它的非确定性终止 = 错误。连接在退出using语句作用域后立即被释放。这与垃圾回收无关。事实上,非确定性GC正是为什么在.NET中引入IDisposable接口和Dispose模式的原因。 - Eric J.
谢谢你们两个。但这就是我在网上找到的冲突信息。在我看来,我需要尽快处理掉所有连接。 - c00000fd
@c00000fd 请查看此处。当连接首次打开时,将基于精确匹配算法创建一个连接池,并将该池与连接字符串中的连接相关联。 - Jeremy Thompson
显示剩余3条评论

1
如果使用using,则不需要关闭它,因为它在内部调用Dispose()
以下是有关ADO.NET中using关键字的一些详细信息,可能值得阅读。 利用C#中的"using"关键字 在@SO上进行快速搜索将引导您到此帖子,您也可以在那里找到答案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接