7

今天早些时候,我在我们的一个项目中发现了一个错误——与永远不会关闭的数据库有一个连接,我的意思是永远不会调用 Close() 方法。但是,当我关闭应用程序时,连接已关闭(多次在 sql management studio 中检查)。为什么?

4

4 回答 4

4

当应用程序退出时,连接将关闭。阅读SqlConnection 的 Finalize。来自 MSDN 的Object.Finalize文档:

“在应用程序域关闭期间,会自动对不能免于终结的对象调用终结,即使是那些仍可访问的对象。”

于 2009-06-19T14:46:54.537 回答
2

这里要记住的另一件事是,在 .Net 中,您可以将连接包装在 using 块中,这将关闭并为您处理连接。因此,如果您在那里有 using 块,那么缺少明确的 Close() 并不是一件坏事......

// this using block will auto close & dispose your connection...
using (var conn = new SqlConnection(...))
{
    conn.Open();
    // database code here with no explicit close

}

这与在 finally 中带有 conn.close 的 try/finally 块的功能等效。许多开发人员忽略了 using 块 - 确保在这种情况下你没有做同样的事情。

如果您确实重写了代码以关闭连接 - 最好在所有数据库对象(连接、命令、读取器)周围使用 Using 块,以确保它们在超出 using 块的范围时正在关闭和处置. 我肯定会建议将它们写入您的代码,而不仅仅是 conn.Close() 在需要的地方。

于 2009-06-19T14:55:32.147 回答
1

SQL 连接的创建成本很高,ADO.NET 使用一种称为连接池的技术,允许重用它们。

引用MSDN

强烈建议您在使用完连接后始终关闭连接,以便将其返回连接池并重新使用。

如果已达到最大池大小并且没有可用的连接可用,则将请求排队。然后,池程序尝试回收任何连接,直到达到超时(默认值为 15 秒)。如果 pooler 在连接超时之前无法满足请求,则会引发异常。

于 2009-06-19T14:49:22.707 回答
1

当您以常规方式退出应用程序时,我希望终结器能够运行。如果连接仍然打开,他们将关闭连接。只是不要依赖这一点:这些终结器可能需要一段时间才能在您的应用程序的正常操作中运行,因此您将保持打开太多连接。

当应用程序崩溃时,终结器可能不会运行,使连接在应用程序的生命周期之后保持打开状态。

于 2009-06-19T14:53:25.693 回答