C#是否需要关闭SqlConnection和SqlDataReader?

4

我有这样一段代码:


SqlConnection conn;
string strconString = System.Configuration.ConfigurationManager.ConnectionStrings["SQLCONN"].ToString();
conn = new SqlConnection(strconString);
string cmdstr = "select status from racpw where vtgid = " + vtgid;
SqlCommand cmdselect = new SqlCommand(cmdstr, conn);
conn.Open();
SqlDataReader dtr = cmdselect.ExecuteReader();
if (dtr.Read())
{
return;
}
else
{
...
}
dtr.Close();
conn.Close();

现在我的问题是,如果返回,我的连接和dtr是否会自动关闭,还是我应该使用一个布尔变量,在我的连接关闭后执行返回?
4个回答

10

在返回之前,您必须关闭连接。

最佳方法是使用块(Using block),因为SqlConnection实现了IDisposable接口。在这种情况下,即使抛出异常,您也不必记得关闭连接。

请参见下面的示例:

using (var conn = new SqlConnection(strconString))
{
    string cmdstr = 
        "select status from racpw where vtgid = " + vtgid;
    using (var cmdselect = new SqlCommand(cmdstr, conn))
    {
        conn.Open();
        using(var dtr = cmdselect.ExecuteReader())
        {
            if (dtr.Read())
            {
                return;
            }
            else
            {
                ...
            }
        }
    }
}

4

你最好使用using块。这将强制在方法中间返回时调用Dispose

string strconString = System.Configuration.ConfigurationManager
    .ConnectionStrings["SQLCONN"].ToString();

using (SqlConnection conn = new SqlConnection(strconString))
{
    string cmdstr = 
        "select status from racpw where vtgid = " + vtgid;

    using(SqlCommand cmdselect = new SqlCommand(cmdstr, conn))
    {
        conn.Open();
        using( SqlDataReader dtr = cmdselect.ExecuteReader())
        {
            if (dtr.Read())
            {
                return;
            }
            else
            {
                ...
            }
        }
    }
}

这能够正常工作是因为using实际上是一个try/finally块,即使你返回了,也会执行finally块并运行Dispose在你的SqlCommandSqlDataReader上。

4

以下是如何提高您的代码质量:

var connectionString = System.Configuration.ConfigurationManager
    .ConnectionStrings["SQLCONN"].ToString();

using (var conn = new SqlConnection(connectionString))
{
    conn.Open();
    using (var cmd = conn.CreateCommand())
    {
        cmd.CommandText = 
            "select status from racpw where vtgid = @vtgid";

        cmd.Parameters.AddWithValue("@vtgid", vtgid);

        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                ...
            }
        }
    }
}

这样你就不需要担心关闭、释放资源等问题了。


1

正如其他人所指出的那样,SqlConnection实现了IDisposable接口。IDisposable存在的目的是让您控制资源何时被释放。如果您不自己调用Dispose方法,您的连接仍将自动关闭,但您无法控制这可能发生的时间(FYI,这将在垃圾回收器收集对象时发生)。


但他可能使用连接池。这意味着,连接不会被垃圾回收器关闭。在这种情况下,当他尝试创建和打开一个新的连接时,他将面临InvalidOperationException。 - Egor4eg

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