如何关闭一个被遗忘的连接?

时间:2012-04-17 19:29:44

标签: c# sqldatareader sqlconnection

我创建了一个连接和一个SqlReader,但忘了关闭它们:

SqlConnection conn = new SqlConnection("connection info");
conn.Open();

string sql = "SQL command HERE";
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader reader = cmd.ExecuteReader();

现在,当尝试再次运行代码时,它总是给我这个错误:

System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.

link告诉我如何正确打开和关闭连接,但没有解释如何关闭仍在运行的连接。

我试过把电脑放下来,我试着查看SQL服务器上的数据库选项(发现没有用)...我改变了代码,只关闭连接和读取器(它编译和运行但是更改代码后问题仍然存在。)

如何关闭此“幽灵”连接?有没有办法(蛮力)关闭所有正在运行的连接?


[编辑:] 我无法真正解决问题。解决方法是将MultipleActiveResultSets=true添加到连接字符串

6 个答案:

答案 0 :(得分:4)

我认为你不能访问幽灵对象,以后,只要在可能的地方使用using构造:

using(SqlConnection conn = new SqlConnection("connection info"))
{
   conn.Open();

   string sql = "SQL command HERE";
   SqlCommand cmd = new SqlCommand(sql, con);
   SqlDataReader reader = cmd.ExecuteReader();
....
}

答案 1 :(得分:3)

将创作包裹在using statement中 - 这将始终确保连接已关闭:

using(SqlConnection conn = new SqlConnection("connection info"))
{
   // your code
}

答案 2 :(得分:1)

所有这些答案都告诉你如何避免这个问题,但是他们没有解释问题所在。

SqlDataReader提供仅向前数据访问,这意味着一旦您使用它并完成,您必须关闭创建一个新的。 See this blog详细解释。基本上,如果你没有关闭DataReader,那么它将保持开放,专用于该连接和命令。

正如其他人所说,最好确保你关闭所有资源。

using (SqlConnection connection = new SqlConnection("...")) {
    connection.Open();

    string sql = "SQL command HERE";

    using (SqlCommand cmd = new SqlCommand(sql, con))
    using (SqlDataReader reader = cmd.ExecuteReader()) {
            // do your stuff
    }
}

答案 3 :(得分:1)

看看所有答案,他们似乎告诉你如何避免这个问题。

如果我没弄错的话,你的意思是客户端(你的PC)和服务器(sql server)上都存在连接,因为你忘了关闭它,你担心它会挂掉永远在那里。

将您与服务器的连接视为电话对话。我可以挂断你,但你的手机需要几秒钟才能意识到连接丢失了。你可能坐在那里想知道我是否挂了电话,或者只是停止说话。你真的不知道。这是连接未正确关闭时服务器上发生的情况。 (在较旧的固定电话上,您可以将电话从电话中取出并无限期地捆绑线路。)

通过在代码中关闭连接,您有效地告诉服务器在关闭连接之前关闭它们的连接。如果您未能关闭连接,当程序退出或重新启动时,它将在您的端部关闭,但服务器可能会以打开的连接坐在那里。 (想想有人坐在那里,想知道“他只是挂在我身上吗?”)

如果我没有弄错的话,你想要的是在SQL服务器端关闭它。 (让他们“挂断”。)

重新启动后,您的 绝对 已关闭。它应该在服务器上自行清除。

但是,如果您想自己动手,可以使用以下信息在代码端的服务器上清除它:How do you kill all current connections to a SQL Server 2005 database?

更简单的方法是在SQL Server Management Studio中执行此操作,如下所述:http://www.mikebevers.be/blog/2009/07/kill-open-sql-processes-connections/

答案 4 :(得分:0)

即使您“关闭”或“处置”某个连接,它也不会真正消失,除非您在连接字符串中明确禁用了Pooling。但是你可以这样做

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.clearpool.aspx

答案 5 :(得分:0)

我知道这是一个老帖子,这对任何人都没有帮助。但我看到有机会发布我在这个问题上看错了。

首先,您正在创建名为conn的SqlConnection,但在名为cmd的SqlCommand中,您将con作为连接。这是一个问题:

SqlConnection conn = new SqlConnection("connection info");
conn.Open();

string sql = "SQL command HERE";
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader reader = cmd.ExecuteReader();

这可能是它给你错误的原因:

System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.

其次,在你完成后关闭一个conn你使用:

conn.Close();

第三,关闭你使用的SqlDataReader:

reader.Close();

但您刚刚将SqlDataReader分配给了读者。你从未真正打开过SqlDataReader。要打开它,请使用:

reader.Read();

或者:

while (reader.Read())
{
    // Code
}

现在是在打开和关闭它们时初始化连接和SqlDataReader的正确方法:

using (SqlConnection conn = new SqlConnection(sqlConnectionString))
{
    conn.Open();

    using (SqlCommand cmd = new SqlCommand())
    {
        cmd.Connection = conn;
        cmd.CommandText = "SELECT * FROM TableName;";

        SqlDataReader reader = cmd.ExecuteReader();

        reader.Read();

        if (reader.HasRows)
        {
            strCol1 = reader.GetValue(0).ToString();
        }

        reader.Close();
  }

  conn.Close();
}