2008-10-20 15 views
6

durante las pruebas beta, descubrimos los mensajes de error de la agrupación de conexiones. Por lo tanto, he estado revisando el código y cerrando los objetos SqlDataReader dondequiera que se hayan dejado sin cerrar. Lo que necesito saber es cómo cerrar un lector de datos (o si es necesario cerrarlo) que se especifica en el atributo SelectStatement de las etiquetas SqlDataSource u ObjectDataSource. ¿Podría haber una fuga de conexión si no se manejan?cómo cerrar la conexión/lector de datos al usar SqlDataSource o ObjectDataSource

¡Gracias de antemano!

Respuesta

12

Tiendo a utilizar la palabra clave "usar", especialmente cuando se trata de abrir y cerrar conexiones a una base de datos. "using" es un acceso directo al patrón Dispose - here es un enlace a la grabación de MSDN, y here es un enlace a una entrada de blog útil con una visión general.

+1

Lo mismo aquí. Me sorprende cuántos desarrolladores escriben código que no utiliza la palabra clave 'usar' para eliminar objetos automáticamente (especialmente cuando se usan cosas como lectores de datos). – Mun

2

Tengo entendido que con SqlDataSource, la gestión de la conexión se realiza para usted, y no tiene nada que temer.

ObjectDataSource no habla directamente con la base de datos en primer lugar, por lo que será seguro, siempre que el objeto subyacente realice su conexión y la gestión del lector correctamente.

Como han mencionado otros, Close() y son sus amigos para las clases que usa con ObjectDataSource.

Mi corazonada es que si has depurado la base de código de forma efectiva, probablemente hayas erradicado el problema.

0

Creo que SqlDataSource se encargará de sus propios problemas de conexión/lector, por lo que no se preocupe. En cuanto a sus conexiones manuales, he encontrado este patrón útil en el pasado:

using (SqlConnection connection = new SqlConnection(connectionString)) 
    { 
     try 
     { 
     SqlCommand command = connection.CreateCommand(); 
     command.CommandText = ... 

     connection.Open(); 
     using (SqlDataReader reader = command.ExecuteReader()) 
     { 
      do 
      { 
       while (reader.Read()) 
       { 
        ... handle each row ... 
       } 
      } while (reader.NextResult()); 
     } 
     } 
     catch (Exception ex) 
     { 
      ... error handling ... 
     } 
     finally 
     { 
     if (connection != null && connection.State == ConnectionState.Open) 
     { 
      connection.Close(); 
     } 
     } 
    } 
-1

estoy de acuerdo, que para el ObjectDataSource el cierre debe ser manejado por su Seleccione el método. Mi método ObjectDataSource Select devuelve un SqlDataReader. Mi preocupación es ... ¿se volverá inútil el SqlDataReader cuando se cierre después de devolverlo a la interfaz de usuario? p.ej. vea el siguiente código de muestra. No lo he probado y no quiero hacerlo en esta etapa de desarrollo.

SqlDataReader MySelectMethod(){ 
    SqlDataReader dr = null; 
    try{ 
     dr = DBObject.GetDataReader(); 
     return dr; 
    } 
    finally{ 
     dr.Close(); 
    } 
} 

¡Gracias por todas las entradas recibidas hasta el momento!

...........

Mi entendimiento es que con SqlDataSource, gestión de conexión se realiza para usted, y usted tiene nada que temer.

ObjectDataSource no habla con la base de datos directamente en el primer lugar, por lo que será seguro - siempre y cuando el objeto subyacente desarrolle correctamente su gestión conexión y lector de .

Como otros han mencionado, Close() y utilizando son tus amigos de las clases se utilizan con ObjectDataSource

.

+0

Esto no funcionará. Como está en un bloque finally, el cierre se ejecutará cuando se produzca el retorno (el código sale del bloque try y se ejecuta finalmente). – tvanfosson

4

Para mejorar el rendimiento de Cerrar()/Deshacer() considere llamar a Cancelar() en el objeto de comando asociado antes de eliminar o cerrar el lector, especialmente cuando no llegó al final del conjunto de registros.

Por ejemplo:

  using (var cmd = ...)) 
      { 
       using (var reader = (DbDataReader) cmd.ExecuteReader()) 
       { 
        try 
        { 
         ConsumeData(reader); // may throw 
        } 
        catch(Exception) 
        { 
         cmd.Cancel(); 
         throw; 
        } 
       } 
      } 
2

Nos tenían los mismos problemas aquí en un entorno de producción.

Ha resuelto el problema. El problema primero era que no había ninguna declaración de uso en mi código. (Fue construido hace unos años, con algunos menos conocimientos).

Intenté poner SqlDataSource en una cláusula de uso. Pero esto tampoco ayudó.

El truco aquí es, al igual que tvanfosson y Mischa sugieren, poner al lector en una cláusula de uso. Este es el objeto que realmente cierra la conexión.

El número de conexiones reducidas al tamaño de grupo mínimo de 10 a carga media.

Cuestiones relacionadas