Mucha gente piensa que el método Dispose () se llama internamente en el método Close (), por lo que no existe una diferencia esencial. De hecho, esta opinión no es muy precisa.
Para algunas clases, es cierto que no existe una diferencia esencial entre Close() y Dispose(), ¡pero para algunas clases este no es el caso!
Primero, veamos la diferencia entre el método Close() y el método Dispose() de SqlConnection que usamos con más frecuencia:
El método Dispose() de la clase SqlConnection se hereda de la clase Component. El código fuente es el siguiente:
eliminación pública vacía () {
Dispose(true); // Llama a una sobrecarga de Dispose con parámetros
GC.SuppressFinalize(this); //Solicita al sistema que no llame al finalizador del objeto especificado.
}
Eliminación de vacío virtual protegido (eliminación bool) {
si (desechando) {
bloquear (esto) {
if (sitio! = nulo && sitio.Contenedor! = nulo) {
sitio.Contenedor.Remove(esto);
}
si (eventos! = nulo) {
Controlador de EventHandler = (EventHandler)eventos[EventDisposed];
if (handler! = null) handler(this, EventArgs.Empty);
}
}
}
}
La descripción del método Close() de la clase SqlConnection en MSDN es la siguiente:
Cierre la conexión a la base de datos. Este es el método preferido para cerrar cualquier conexión abierta. Si SqlConnection sale del alcance, no se cerrará. porque
Por lo tanto, la conexión debe cerrarse explícitamente llamando a Close o Dispose. Cerrar y Disponer son funcionalmente equivalentes. Si el valor del grupo de conexiones
Agrupación Si se establece en verdadero o sí, la conexión subyacente se devolverá al grupo de conexiones. Por otro lado, si Pooling se establece en falso o no, entonces
La conexión subyacente al servidor está cerrada.
Según la descripción, parece que el método Close() y el método Dispose() son similares. De hecho, solo son equivalentes en la función de cerrar la conexión.
() código fuente del método:
anular el vacío público Cerrar() {
IntPtr hscp;
Bid.ScopeEnter(out hscp, "<sc.SqlConnection.Close|API> %d#", ObjectID);
intentar {
Estadísticas SqlStatistics = nulo;
RuntimeHelpers.PrepareConstrainedRegions();
intentar {
#si DEPURAR
objeto inicialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot);
RuntimeHelpers.PrepareConstrainedRegions();
intentar {
Thread.SetData(TdsParser.ReliabilitySlot, verdadero);
#endif //DEPURACIÓN
estadísticas = SqlStatistics.StartTimer(Estadísticas);
// El bloqueo aquí es para proteger contra el comando.cancel / conexión.cerrar
condición de carrera
// SqlInternalConnectionTds se establece en OpenBusy durante el cierre, una vez que esto
¿Qué sucede? El elenco de abajo fallará y
// el comando ya no será cancelable. Quizás sea conveniente que lo sea.
cancelar la operación de cierre, pero esto es
// fuera del alcance de Whidbey RTM Consulte (SqlCommand::Cancel) para conocer otros.
cerrar con llave.
bloquear (conexión interna) {
InnerConnection.CloseConnection (esto, ConnectionFactory);
}
// no requiere GC.KeepAlive(this) debido a OnStateChange
si (nulo! = Estadísticas) {
ADP.TimerCurrent(fuera _statistics._closeTimestamp);
}
#si DEPURAR
}
finalmente {
Thread.SetData(TdsParser.ReliabilitySlot, inicialReliabilitySlotValue);
}
#endif //DEPURACIÓN
}
atrapar (System.OutOfMemoryException e) {
Abortar(e);
tirar;
}
captura (System.StackOverflowException e) {
Abortar(e);
tirar;
}
captura (System.Threading.ThreadAbortException e) {
Abortar(e);
tirar;
}
finalmente {
SqlStatistics.StopTimer(estadísticas);
}
}
finalmente {
SqlDebugContext sdc = _sdc;
_sdc = nulo;
Oferta.AlcanceLeave(ref hscp);
si (sdc! = nulo) {
sdc.Dispose();
}
}
}
Puede ver que el método Close() no llama al método Dispose(). Aunque hay una línea de sdc.Dispose();, esto solo libera SqlDebugContext.
¡Por ejemplo, no tiene nada que ver con el método SqlConnection.Dispose()!
Entonces, ¿cuál es la diferencia?
El método Close () solo cierra la conexión y luego la conexión se almacena en el grupo de conexiones, por lo que después de llamar al método Close (), aún puede pasar
Método Open() para abrir la conexión y después de llamar al método Dispose(), ¡la conexión ya no se puede utilizar!
Otra diferencia importante es que cuando el método Close() no llama a GC.SuppressFinalize(this);, la consecuencia directa de esto es basura.
Se requieren operaciones de terminación durante el reciclaje, lo que hará que aumente la "edad de generación" de esta instancia, lo que retrasará enormemente el tiempo de reciclaje de este objeto.
Para la clase SqlConnection, si necesita utilizar esta conexión en el futuro, puede utilizar el método Close() para cerrar temporalmente la conexión.
Para usar esta conexión, primero puede usar el método Dispose() para liberar recursos. Por supuesto, puede usar la palabra clave using para simplificar este proceso.
No he encontrado el código fuente de la clase OleDbConnection y la clase OdbcConnection, ¡pero deberían ser similares a la clase SqlConnection!
Veamos una clase de uso común y veamos la diferencia entre el método Close() y el método Dispose() de la clase FileStream:
El método Close() de la clase FileStream se hereda de la clase Stream. El código fuente es el siguiente:
vacío virtual público Cerrar()
{
Disponer (verdadero);
GC.SuppressFinalize(esto);
}
El método Dispose () de la clase FileStream se hereda de la clase Stream. El código fuente es el siguiente:
eliminación pública vacía ()
{
Cerca();
}
Es una implementación del modo Dispose estándar. El método Close() llama al método Dispose con parámetros y luego llama a GC.SuppressFinalize.
(this); Solicita al sistema que no llame al finalizador del objeto especificado. ¡El método Dispose() llama directamente al método Close()!
Para la clase FileStream, no hay diferencia entre el método Close() y el método Dispose().