1

我创建了一个连接和一个 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.

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

我尝试关闭电脑,尝试查看 SQL 服务器上的数据库选项(发现没有用)...我更改了代码以关闭连接和阅读器(它已编译并运行,但问题仍然存在改回代码后)。

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


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

4

6 回答 6

4

我不认为你可以访问 ghost object,为了将来,只要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();
....
}
于 2012-04-17T19:32:04.900 回答
3

将创建包装在一个using语句中- 这将始终确保连接关闭:

using(SqlConnection conn = new SqlConnection("connection info"))
{
   // your code
}
于 2012-04-17T19:31:24.310 回答
1

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

SqlDataReader 提供只进数据访问,这意味着一旦你使用它并完成,你必须关闭创建一个新的。有关详细说明,请参阅此博客。基本上,如果您不关闭 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
    }
}
于 2012-04-17T19:38:24.030 回答
1

查看所有答案,它们似乎告诉您如何避免该问题。

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

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

通过在代码中关闭连接,您实际上是在告诉服务器在关闭您自己的连接之前关闭它们的连接端。如果您无法关闭连接,它将在程序退出或重新启动时关闭,但服务器可能会坐在那里并打开连接。(想想有人坐在那里想知道“他刚刚挂断了我吗?”)

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

重新启动后,它完全关闭。它应该在服务器上自行清除。

但是,如果您想自己执行此操作,您可以在代码端使用以下信息在服务器上清除它:您如何终止与 SQL Server 2005 数据库的所有当前连接?

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

于 2012-04-17T20:01:18.960 回答
0

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

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

于 2012-04-17T19:33:25.583 回答
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 分配给了 reader。您从未真正打开过 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();
}
于 2015-06-02T11:51:05.460 回答