2011-10-24 96 views
6

用C#編寫的一個相當大的Web應用程序不斷拋出2個錯誤:'ExecuteReader需要一個開放且可用的連接。連接的當前狀態是打開的'

'ExecuteReader需要一個開放的可用Connection。連接的當前狀態是打開的。' 和 '當閱讀器關閉時,嘗試調用Read無效。'

這些錯誤是偶發性的 - 大約95%的時間用於加載正確的頁面,但最近它們已經成爲地方病,它們一直在發生,基本上削弱了應用程序的功能。

Web應用程序高度依賴於MS SQL數據庫,並且錯誤似乎並不侷限於只有一頁,而是幾乎所有連接到數據庫的頁面。

查詢是這樣進行的:

Database.Open(); // Custom class that has our connection string hard coded. 

string query = "SELECT * FROM table"; // (dummy query) 
SqlCommand command = new SqlCommand(query, Database.Conn); 

SqlDataReader reader = null; 

try { 
    reader = command.ExecuteReader(CommandBehaviour.CloseConnection); 

    if (reader.HasRows) { 

     while (reader.Read()) { 
      // Do something with the data. 
     } 
    } 
    reader.Close(); 
} 
catch (Exception e) { 
    throw new Exception(e.Message); 
} 
finally { 
    if (reader != null) { 
     reader.Close(); 
    } 
} 

我研究過在網絡上這些錯誤,我已經看到了,我已經試過無濟於事了幾個可能的解決方案:

把使用()塊中的代碼的各個部分。 爲讀者指定CommandBehaviour.CloseConnection。 檢查是否啓用了MARS。 確保每次都創建一個新的連接對象。

我已經花了很多年尋找解決方案,更不用說很長一段時間試圖使它工作,而且我快要把我的頭髮拉出來了!

請幫忙!

編輯 - 修正了問題,請參閱評論部分。

+0

你好,數據庫是一個靜態類來處理連接: '公共靜態類數據庫{ private static string connString =「(已刪除的連接字符串)」; public static SqlConnection Conn = new SqlConnection(connString); public static void Open(){ if(Conn.State == System.Data.ConnectionState.Closed){ Conn.Open(); return; } } }' – surfitscrollit

+0

我已經創建了一個答案,我懷疑:) – leppie

+0

當你不使用數據庫時你會得到預期的行爲嗎?通過讓'Database'類具有這樣的代碼,就可以解耦那些真正應該耦合的東西(SqlDataReader和SqlConnection)。 –

回答

4

除了leppieanswer,你也應該Dispose() ING任何IDisposable類型:

 try 
     { 
      Database.Open(); // Custom class that has our connection string hard coded. 

      string query = "SELECT * FROM table"; // (dummy query) 

      using (SqlCommand command = new SqlCommand(query, Database.Conn)) 
      using (SqlDataReader reader = command.ExecuteReader(CommandBehaviour.CloseConnection)) 
      { 
       if (reader.HasRows) 
       { 
        while (reader.Read()) 
        { 
         // Do something with the data. 
        } 
       } 
      } 
     } 
     catch (Exception e) 
     { 
      throw new Exception(e.Message); 
     } 
6

在我看來,Database是一個類型,而不是一個實例。

您現在正在遇到多線程問題。

你有2種選擇:

  • 通過Database.Open()

  • 製作應用[ThreadStatic]包含創建的連接對象的場Database.Open()返回連接的新實例對象並在構建命令時使用它
相關問題