2011-10-24 14 views
6

Một ứng dụng web khá lớn được viết bằng C# liên tục ném 2 lỗi:'ExecuteReader yêu cầu kết nối mở và có sẵn. Trạng thái hiện tại của kết nối đang mở '

' ExecuteReader yêu cầu kết nối mở và có sẵn. Trạng thái hiện tại của kết nối đang mở. ' và 'Nỗ lực gọi điện không hợp lệ Đọc khi trình đọc bị đóng'.

Các lỗi này không thường xuyên - các trang được sử dụng để tải tốt khoảng 95% thời gian, nhưng gần đây chúng đã trở thành đặc hữu, chúng luôn xuất hiện và làm tê liệt chức năng của ứng dụng.

Ứng dụng web phụ thuộc rất nhiều vào cơ sở dữ liệu MS SQL và các lỗi xuất hiện không chỉ giới hạn ở một trang mà gần như tất cả các trang kết nối với cơ sở dữ liệu.

Các truy vấn được thực hiện như vậy:

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

Tôi đã nghiên cứu các lỗi này trên web và tôi đã nhìn thấy một vài giải pháp tiềm năng mà tôi đã cố gắng để không có kết quả:

Đưa các phần khác nhau của mã trong một khối using(). Chỉ định CommandBehaviour.CloseConnection cho người đọc. Kiểm tra xem MARS đã được bật chưa. Đảm bảo rằng một đối tượng kết nối mới được tạo ra mỗi lần.

Tôi đã dành thời đại tìm kiếm các giải pháp cho điều này, chưa kể một thời gian dài cố gắng để làm cho nó hoạt động, và tôi gần như trên bờ vực của tôi kéo tóc ra ngay bây giờ!

Vui lòng trợ giúp!

EDIT - Khắc phục sự cố, xem phần nhận xét.

+0

Hiya, Cơ sở dữ liệu là một lớp tĩnh để xử lý các kết nối: ' public class tĩnh Database { chuỗi tĩnh riêng connString = "(remove conn string)"; tĩnh công cộng SqlConnection Conn = new SqlConnection (connString); void tĩnh công khai Mở() { nếu (Conn.State == System.Data.ConnectionState.Closed) { Conn.Open(); trả lại; } } } ' – surfitscrollit

+0

Tôi đã tạo câu trả lời, tôi nghi ngờ rằng :) – leppie

+0

Bạn có nhận được hành vi mong đợi khi không sử dụng' Cơ sở dữ liệu' không? Bởi vì có 'Database' lớp _and_ có mã như thế này, bạn đang tách những thứ (SqlDataReader & SqlConnection) mà thực sự cần được kết hợp. –

Trả lời

4

Ngoài leppie 's answer, bạn cũng nên Dispose() ing của bất kỳ IDisposable loại:

 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

Dường như với tôi rằng Database là một loại chứ không phải là một thể hiện.

Hiện tại, bạn đang gặp sự cố đa luồng.

Bạn có 2 lựa chọn:

  • Áp dụng [ThreadStatic] đến lĩnh vực có chứa các đối tượng kết nối được tạo ra bởi Database.Open()

hoặc

  • Make Database.Open() trở lại một trường hợp trong lành của kết nối đối tượng và sử dụng khi xây dựng lệnh
Các vấn đề liên quan