2012-04-17 58 views
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. 

link告訴我如何正確地打開和關閉連接,但沒有解釋如何關閉仍在運行的任何東西。我試圖在SQL服務器上查看數據庫的選項(發現沒有用)...我改變了代碼,只做了連接和閱讀器的關閉(編譯和運行但改回代碼後問題仍然存在)。

如何關閉此「鬼」連接?有什麼方法(蠻力)關閉所有正在運行的連接?


[編輯:]我不能真正解決問題。解決方法是添加MultipleActiveResultSets=true到連接字符串

+0

爲你應該使用備查正如許多人所寫的那樣,using()語句。但是,要解決阻塞問題,請嘗試重新啓動MSSQLSERVER實例(如果它不在生產環境中)。 – Jim 2012-04-17 19:50:56

回答

1

看着所有的答案,他們似乎告訴你如何避免這個問題。

如果我沒有弄錯,你的意思是客戶端(你的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

3

裹建立在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

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(); 
.... 
} 
+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

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

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.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(); 
}