Beaucoup de gens pensent que la méthode Dispose() est appelée en interne dans la méthode Close(), il n'y a donc pas de différence essentielle ! En fait, cette vision n’est pas très exacte.
Pour certaines classes, il est vrai qu’il n’y a pas de différence essentielle entre Close() et Dispose(), mais pour certaines classes ce n’est pas le cas !
Tout d’abord, regardons la différence entre la méthode Close() et la méthode Dispose() de SqlConnection que nous utilisons le plus souvent :
La méthode Dispose() de la classe SqlConnection est héritée de la classe Component. Le code source est le suivant :
public void Dispose() {
Dispose(true); //Appelle une surcharge de Dispose avec des paramètres
GC.SuppressFinalize(this); //Demander au système de ne pas appeler le finaliseur de l'objet spécifié.
}
protected virtual void Dispose(bool disposition) {
si (disposer) {
verrouiller(ce) {
if (site != null && site.Container != null) {
site.Container.Remove(this);
}
si (événements != null) {
Gestionnaire EventHandler = (EventHandler)events[EventDisposed];
if (handler != null) handler(this, EventArgs.Empty);
}
}
}
}
La description de la méthode Close() de la classe SqlConnection dans MSDN est la suivante :
Fermez la connexion à la base de données. Il s’agit de la méthode préférée pour fermer toute connexion ouverte. Si SqlConnection est hors de portée, il ne sera pas fermé. parce que
Par conséquent, la connexion doit être fermée explicitement en appelant Close ou Dispose. Close et Dispose sont fonctionnellement équivalents. Si la valeur du pool de connexions
Pooling Si la valeur est true ou yes, la connexion sous-jacente sera renvoyée au pool de connexions. D'un autre côté, si Pooling est défini sur false ou no, alors
La connexion sous-jacente au serveur est fermée.
D'après la description, il semble que la méthode Close() et la méthode Dispose() soient similaires. En fait, elles ne sont équivalentes que dans la fonction de fermeture de la connexion.
() code source de la méthode :
remplacer public void Close() {
IntPtr hscp ;
Bid.ScopeEnter(out hscp, "<sc.SqlConnection.Close|API> %d#" , ObjectID);
essayer {
Statistiques SQLStatistics = null ;
RuntimeHelpers.PrepareConstrainedRegions();
essayer {
#si DÉBOGAGE
objet initialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot);
RuntimeHelpers.PrepareConstrainedRegions();
essayer {
Thread.SetData(TdsParser.ReliabilitySlot, true);
#endif //DEBUG
statistiques = SqlStatistics.StartTimer(Statistiques);
// Le verrou ici sert à protéger contre la commande.cancel / connection.close
condition de course
// Le SqlInternalConnectionTds est défini sur OpenBusy lors de la fermeture, une fois ceci
que se passe-t-il, le casting ci-dessous échouera et
// la commande ne sera plus annulable. Il pourrait être souhaitable de l'être.
capable d'annuler l'opération de fermeture, mais c'est
// en dehors de la portée de Whidbey RTM Voir (SqlCommand::Cancel) pour les autres.
verrouillage.
verrouiller (InnerConnection) {
InnerConnection.CloseConnection(this, ConnectionFactory);
}
// ne nécessite pas GC.KeepAlive(this) à cause de OnStateChange
if (null != Statistiques) {
ADP.TimerCurrent(out _statistics._closeTimestamp);
}
#si DÉBOGAGE
}
enfin {
Thread.SetData(TdsParser.ReliabilitySlot, initialReliabilitySlotValue);
}
#endif //DEBUG
}
catch (System.OutOfMemoryException e) {
Abandonner(e);
lancer;
}
catch (System.StackOverflowException e) {
Abandonner(e);
lancer;
}
catch (System.Threading.ThreadAbortException e) {
Abandonner(e);
lancer;
}
enfin {
SqlStatistics.StopTimer(statistiques);
}
}
enfin {
SqlDebugContext sdc = _sdc;
_sdc = nul ;
Bid.ScopeLeave(réf hscp);
si (sdc != null) {
sdc.Dispose();
}
}
}
Vous pouvez voir que la méthode Close() n'appelle pas la méthode Dispose(). Bien qu'il existe une ligne de sdc.Dispose();, cela libère uniquement le SqlDebugContext.
Par exemple, n'a rien à voir avec la méthode SqlConnection.Dispose() !
Alors quelle est la différence ?
La méthode Close() ferme uniquement la connexion, puis la connexion est stockée dans le pool de connexions, donc après avoir appelé la méthode Close(), vous pouvez toujours passer
Méthode Open() pour ouvrir la connexion et après avoir appelé la méthode Dispose(), la connexion ne peut plus être utilisée !
Une autre différence importante est que lorsque la méthode Close() n’appelle pas GC.SuppressFinalize(this);, la conséquence directe est un déchet.
Des opérations de terminaison sont nécessaires lors du recyclage, ce qui fera augmenter « l'âge de génération » de cette instance, retardant ainsi considérablement le temps de recyclage de cet objet !
Pour la classe SqlConnection, si vous devez utiliser cette connexion à l'avenir, vous pouvez utiliser la méthode Close() pour fermer temporairement la connexion.
Pour utiliser cette connexion, vous pouvez d'abord utiliser la méthode Dispose() pour libérer des ressources. Bien entendu, vous pouvez utiliser le mot-clé using pour simplifier ce processus.
Je n'ai pas trouvé le code source de la classe OleDbConnection et de la classe OdbcConnection, mais ils devraient être similaires à la classe SqlConnection !
Examinons une classe couramment utilisée et voyons la différence entre la méthode Close() et la méthode Dispose() de la classe FileStream :
La méthode Close() de la classe FileStream est héritée de la classe Stream. Le code source est le suivant :
vide virtuel public Fermer()
{
Disposer(vrai);
GC.SuppressFinalize(this);
}
La méthode Dispose() de la classe FileStream est héritée de la classe Stream. Le code source est le suivant :
public void Disposer()
{
Fermer();
}
Il s'agit d'une implémentation du mode Dispose standard. La méthode Close() appelle la méthode Dispose avec des paramètres, puis appelle GC.SuppressFinalize.
(this); Demande au système de ne pas appeler le finaliseur de l'objet spécifié. La méthode Dispose() appelle directement la méthode Close() !
Pour la classe FileStream, il n'y a pas de différence entre la méthode Close() et la méthode Dispose() !