2009-06-19 5 views
5

J'ai soupçonné qu'une connexion à une base de données utilisée dans l'une de nos applications n'est pas toujours fermée. Je suis allé voir le code et j'ai trouvé une classe DataProvider qui a SqlConnection objet. La connexion est ouverte dans le constructeur de cette classe et fermée dans sa méthode Dispose (ne jugez pas cela, je sais que garder une connexion ouverte est mauvaise, ce n'est juste pas mon code et ce n'est pas le point de la question de toute façon). La méthode Dispose est mis en œuvre comme ceci:La fermeture d'une connexion de base de données dans la méthode Dispose est-elle correcte?

protected virtual void Dispose(bool disposing) 
{ 
    if (!_disposed) 
    { 
     if (disposing) 
     { 
      if (_conn != null) 
       _conn.Close(); 
     } 

     _disposed = true; 
    } 
} 

La question est:
garantit-il toujours que la connexion est fermée?
Ce code est-il correct?

Je pense qu'il devrait être _conn.Dispose() appelé - ai-je raison et pourrait-il affecter la fermeture de la connexion (probablement pas)?

+0

Si vous avez un soupçon confirmer en vérifiant à l'aide des compteurs de performance. – RichardOD

+0

Une valeur clé à vérifier est NumberOfPooledConnections. – RichardOD

Répondre

8

Dispose n'est jamais appelé automatiquement.

La connexion ne sera pas fermée jusqu'à ce que la méthode Dispose de votre objet est explicitement appelé, ou si votre classe utilisé dans l'aide() bloquer

Une façon plus sûre consiste à appeler la méthode Éliminez dans votre finaliseur et Assurez-vous que le finaliseur est supprimé lorsque la méthode Dispose est appelée.

This article présente la bonne façon de mettre en œuvre le modèle

Hope it helps!

Cédric

+0

ok mais si l'application est fermée (normalement ou par une erreur) la méthode d'élimination sera appelée et la connexion sera fermée? – agnieszka

+0

Lorsque votre application est arrêtée, tous les finaliseurs doivent être appelés par le garbage collector, donc au moins les connexions seront fermées car le finalizer des objets Connection sera déclenché ... mais c'est une façon boiteuse de fermer une connexion; –

+1

Et d'ailleurs: les méthodes Dispose ne sont jamais appelées automatiquement.Dans votre état de code actuel, les connexions sont fermées parce que la méthode de connexion de Connection est appelée dans leurs finaliseurs –

2

conn.Dispose(); va également fermer la connexion, donc ne peut pas nuire à changer pour suivre le modèle de disposition.

Mais là fonctionnellement équivalent donc il doit y avoir un autre problème où.

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.close.aspx

Si le SqlConnection sort de portée, il ne sera pas fermé. Par conséquent, vous devez fermer explicitement la connexion en appelant Close ou Dispose. Fermer et éliminer sont fonctionnellement équivalent. Si la valeur de mise en pool de connexions de connexion est définie sur true ou yes, la connexion sous-jacente est renvoyée au pool de connexions . D'autre part, si Pooling est défini sur false ou no, la connexion sous-jacente au serveur est fermée.

Questions connexes