如何关闭被遗忘的连接?

问题描述:

我创建了一个连接和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到连接字符串

+0

为你应该使用备查正如许多人所写的那样,using()语句。但是,要解决阻塞问题,请尝试重新启动MSSQLSERVER实例(如果它不在生产环境中)。 – Jim 2012-04-17 19:50:56

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

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

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

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

如果我没有弄错,你想要的是在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/

+0

这正是我的问题,正是我需要解决我的问题!非常感谢!对于使用SQL Server 2008的用户,我建议选中[link](http://social.msdn.microsoft.com/Forums/en-US/sqldatabaseengine/thread/5cb020b5-44fb-465c-9efb-b789763f947e/)以查找“Activity监视器“选项(他们改变了它的位置)。 – dialex 2012-04-17 21:37:51

裹建立在using statement - 这将始终确保连接被关闭:

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

是的,我发现在我添加到我的OP的链接上。但我的问题是,只适用于将来的呼叫,它不会关闭我的连接。 – dialex 2012-04-17 19:32:23

+1

@DiAlex - 我不太明白你的意思。只要应用程序存在,连接就会关闭。您看到的错误是由于您在重新使用连接之前没有关闭连接。 – Oded 2012-04-17 19:33:28

+0

好吧,那很好。但是每次运行应用程序时都会创建一个新的连接,所以“重用问题”不应该存在,因为我正在使用新连接,对吧?顺便说一句,在using语句,连接或SqlDataReader中应该是什么?Thx – dialex 2012-04-17 20:59:11

我不认为你可以访问鬼对象 ,为未来,只是用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(); 
.... 
} 
+0

再次,我不能创建一个新的连接“正确的方式”,直到我关闭了前一个。 – dialex 2012-04-17 19:32:58

+0

如果'conn'是一个全局变量,你可以看看[ConnectionState](http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.state.aspx)属性了解连接是否仍然打开,请关闭它。 – Tigran 2012-04-17 19:34:37

+0

@DiAlex - 在重新编译应用程序并重新部署应用程序时,您到底具有开放连接? – Oded 2012-04-17 19:34:40

说实话,即使你“关闭”或连接的“处置”这并不意图只有在显式禁用连接字符串中的连接池时才会离开。然而,你可以做到这一点

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

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

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 
    } 
} 
+0

用于提及多个使用语句。 Thx的链接,虽然我在我的OP上提到它:P – dialex 2012-04-17 21:03:31

+0

啊没有看到它。在此监视器上,您帖子中的链接与正常文本几乎相同。 ;)无论如何,我希望这对你有帮助。您遇到问题的主要原因是在ADO.NET框架(.NET的一部分以及DataReader的一部分)中,并且因为您有一个全局变量(从其他评论/答案/您的答复中听到的内容) ,它保留了对资源的引用,这就是为什么你不能重新使用它。 – 2012-04-17 21:17:36

+0

顺便说一下,我用你的代码,并检查了“活动监视器”,如大卫斯特拉顿所述,并且连接仍然没有在执行结束时被关闭。当我按顺序调用两个使用相同连接的方法时,我得到相同的错误,而当我调用两次时,相同的方法一切顺利。 – dialex 2012-04-17 21:42:15

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

首先,您正在创建一个名为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.Close(); 

三,关闭您使用的SqlDataReader:

reader.Close(); 

但是您只是将SqlDataReader分配给阅读器。你从来没有真正打开过SqlDataReader。要打开它使用:

reader.Read(); 

或者:

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

我们initilaize连接和一个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(); 
}