2011-10-24 117 views
6

Una aplicación web bastante grande escrita en C# sigue arrojando 2 errores:'ExecuteReader requiere una conexión abierta y disponible. El estado actual de la conexión está abierto '

' ExecuteReader requiere una conexión abierta y disponible. El estado actual de la conexión está abierto. y 'Intento no válido de llamar a Read cuando el lector está cerrado.'

Estos errores fueron esporádicos: las páginas solían cargar bien aproximadamente el 95% del tiempo, pero recientemente se han vuelto endémicas, están ocurriendo todo el tiempo y básicamente paralizando la funcionalidad de la aplicación.

La aplicación web depende en gran medida de una base de datos MS SQL, y los errores parecen no estar limitados a una sola página, sino a casi todas las páginas que se conectan a la base de datos.

Las consultas se realizan como tales:

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

He investigado estos errores en la web y he visto algunas soluciones potenciales que he intentado en vano:

Poniendo varias partes del código en un bloque using(). Especificando CommandBehaviour.CloseConnection para el lector. Verificando que MARS esté habilitado. Asegurándose de que se crea un nuevo objeto de conexión cada vez.

¡He pasado años buscando soluciones para esto, sin mencionar un largo tiempo tratando de hacerlo funcionar, y estoy a punto de arrancarme el pelo ahora!

Por favor ayuda!

EDITAR - Solucionado el problema, vea la sección de comentarios.

+0

Hiya, base de datos es una clase estática para manejar la conexión: 'base de datos de clase public static { cadena estática privada connString = "(cadena de conexión eliminada)"; public static Conq SqlConnection = new SqlConnection (connString); public static void Open() { if (Conn.State == System.Data.ConnectionState.Closed) { Conn.Open(); devolución; } } } ' – surfitscrollit

+0

He creado una respuesta, sospechaba que :) – leppie

+0

¿Obtienes el comportamiento esperado cuando no usas' Database'? Al tener esa clase 'Database' _and_ con un código como este, estás desacoplando cosas (SqlDataReader & SqlConnection) que realmente deberían estar acopladas. –

Respuesta

4

Además de leppie 's answer, también debe ser Dispose() ción de cualquier IDisposable tipos:

 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

Me parece que Database es un tipo y no una instancia.

Ahora se encuentra con problemas de subprocesamiento múltiple.

tiene 2 opciones:

  • aplicar el [ThreadStatic] al campo que contiene el objeto de conexión creado por Database.Open()

o

  • Hacer Database.Open() devolver un nuevo ejemplo de la conexión objetar y usar eso al construir el comando
Cuestiones relacionadas