Pregunta

durante las pruebas beta descubrimos mensajes de error de 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 datareader (o si es necesario cerrar) que se especifica en el atributo SelectStatement de las etiquetas SqlDataSource o ObjectDataSource. ¿Podría haber una fuga de conexión si no se manejan?

Gracias de antemano!

¿Fue útil?

Solución

Tiendo a usar " usando " palabra clave, especialmente cuando se trata de abrir y cerrar conexiones a una base de datos. " utilizando " es un acceso directo al patrón de Disposición - aquí es un enlace a la redacción de MSDN y aquí es un enlace a una entrada de blog útil con una visión general.

Otros consejos

Para mejorar el rendimiento de Close () / Dispose (), considere la posibilidad de llamar a Cancel () en el objeto de comando asociado antes de deshacerse 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;
                    }
                }
            }

Entiendo que con SqlDataSource , la administración de la conexión se realiza por usted y no tiene nada que temer.

ObjectDataSource no se comunica directamente con la base de datos, por lo que será seguro, siempre y cuando el objeto subyacente realice su conexión y la administración del lector correctamente.

Como han mencionado otros, Close () y using son tus amigos para las clases que usas con ObjectDataSource .

Mi corazonada es que si ha borrado el código base de manera efectiva, probablemente haya erradicado el problema.

Tuvimos los mismos problemas aquí en un entorno de producción.

Resuelto el problema. El problema primero fue que no había declaraciones de uso en absoluto en mi código. (Fue construido hace unos años, con un poco de conocimiento).

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

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

El número de conexiones se redujo al tamaño mínimo de agrupación de 10 con carga media.

La llamada a .Dispose () debe manejar la limpieza y liberar cualquier recurso retenido, pero . El método Close () también debe llamarse cuando un objeto termina de leer desde el lector .

Creo que el SqlDataSource manejará sus propios problemas de conexión / lector, así 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();
         }
      }
  }

Estoy de acuerdo, que para el ObjectDataSource el cierre debe ser manejado por su método Select. Mi método ObjectDataSource Select devuelve un SqlDataReader. Mi preocupación es ... ¿el SqlDataReader se volverá inútil cuando se cierre después de devolverlo a la interfaz de usuario? p.ej. Vea el siguiente código de ejemplo. 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 ahora!

...........

  

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

     

ObjectDataSource no habla con el   Base de datos directamente en primer lugar,   así será seguro, siempre y cuando el   objeto subyacente realiza su   gestión de conexión y lector   correctamente.

     

Como han mencionado otros, Close () y   Usando son tus amigos para las clases.   usas con ObjectDataSource

.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top