C# - 关闭Sql对象的最佳实践

时间:2008-11-29 21:02:15

标签: c# sql

如果你有一个带有Sqlaccess的C#功能,是否必须关闭所有对象/句柄,或者在退出函数后自动清理所有内容

例如:

void DoSqlStuff()
{
    SqlConnection sqlConn = new SqlConnection(...);
    SqlCommand cmd = new SqlCommand(...);
    SqlDataReader sqlData= null;

    sqlConn,Open();
    sqlData = cmd.ExecutReader();


    while(sqlData.Read())
    {
         ...
    }
}

关闭SqlConn和SqlData是可选的,推荐的还是必需的?

感谢。

8 个答案:

答案 0 :(得分:25)

您应该在完成后立即关闭SqlConnection对象。如果不这样做,则连接将保持打开状态,并且无法处理其他请求。

using语句对此很有用。它将为您调用对象上的Dispose():

using (SqlConnection cn = new SqlConnection(connectionString))
{   
    SqlCommand cm = new SqlCommand(commandString, cn)
    cn.Open();
    cm.ExecuteNonQuery();       
}

答案 1 :(得分:3)

您不需要为SqlDataReader使用单独的using语句(以及一个using语句用于连接),除非您计划在SqlDataReader完全读取行集后对连接执行其他操作。

如果您只是打开一个连接,使用阅读器读取一些数据,然后关闭连接,那么使用整个代码块(围绕连接)的一个语句就足够了,因为垃圾收集器将清理所有资源绑定到第一个使用语句处理的连接。

无论如何,这是一个很好的article,它描述了所有......

答案 2 :(得分:2)

在从函数返回之前,您应该关闭所有内容。 Open datareaders意味着数据库上的开放游标,导致内存使用量增加。数据库连接也是如此。

未使用的对象不会立即在C#中释放,但仅在执行垃圾收集时才会释放,这不是确定性的。

答案 3 :(得分:1)

所有三个类都有Dispose()方法。强制性太强,但强烈建议您使用using关键字,以便自动调用Dispose()。如果不这样做会使您的程序运行“繁重”,使用的系统资源比必要的多。当你不使用“new”关键字足以触发垃圾收集器时,会彻底失败。

答案 4 :(得分:1)

在SQL连接上调用Close实际上不会关闭它,但会将其返回到连接池以便重用,从而提高性能。

另外,当你完成它们时(asap)没有明确处理非托管资源通常是不好的做法。

答案 5 :(得分:1)

在finally语句中显式处理是另一种方法,尽管using语句是一个更好的解决方案。它产生了更多的代码,但展示了目标......

SqlConnection conn = null;
try
{
    //create connection

    SqlCommand cmd = null;
    try
    {
        //create command

        SqlDataReader reader = null;
        try 
        {
            //create reader
        }
        finally
        {
            reader.Dispose();
        }
    }
    finally
    {
        cmd.Dispose();
    }
}
finally 
{
    conn.Dispose();
}

答案 6 :(得分:1)

这里要小心绝对。很大程度上取决于你在做什么&低效率可能存在的地方。 在每个用户都有一个单独的安全上下文的Web页面中,您可能别无选择,只能使用每个页面命中的新安全凭据建立新的SQL连接。如果您可以使用具有共享安全上下文的SQL连接池,那么显然更好。让网页过滤结果,但也许你不能。

在早期版本的SQL Server即(v6.5或更低版本)中,登录验证由SQL Server完成。此外,SQL受连接内存和放大器的严重限制。它可以处理的活动连接数。因此,在不使用时断开连接是一个好主意。 在v6.5之后,大多数人使用Windows身份验证登录SQL。这导致服务器和服务器之间的大量网络呼叫。一些延迟。 Kerberos安全性更加繁琐,因此建立SQL连接非常昂贵。因此,您需要在WinForms应用程序的生命周期中保持连接打开与打开和放置之间找到平衡。在每个方法调用中关闭它。

作为一个粗略的指南,如果你认为你的应用程序想要在下一次与SQL交谈,比如30秒。保持已建立的连接打开。如果他们已经最小化了你的应用程序,没有在超时期限内触摸它,或者你已经获得了RAM中的所有数据。他们不太可能从SQL系统中获得更多东西。关闭连接。

考虑创建一个带有系统计时器的类来保持连接。您的班级将始终提供有效的连接,但是班级可能会选择放弃它。适当时释放SQL上的连接负载。

除非您也在编写基于服务器的代码,否则可能甚至不会注意到少量的内存效率低下。但是有2-10,000名客户使用您的安全和放大数据服务器可能会使您的数据中心陷入困境。

答案 7 :(得分:0)

任何处理像Connections这样的SQL东西的类都应该实现Microsoft .NET编码指南所述的IDisposable接口。

因此,您应该关闭并在Dispose方法中处理连接。