2015-10-07 2 views
1

J'ai essayé de fermer une connexion dans le destructeur de ma classe, pour être sûr que si j'oublie de le fermer - il se ferme automatiquement, et il déclenche une exception.fermer la connexion dans le destructeur

J'ai cherché un peu et j'ai fondé here que cela ne peut être fait.

Maintenant, j'ai essayé de le fermer deux fois - et ça marche !!! Mais je me demande si c'est une bonne solution. qu'en pensez-vous?

est ici le code

public class MyCommand : IDisposable 
{ 
    public readonly DbCommand command; 
    public MyCommand(string ConnectionString, DbProviderFactory factory) 
    { 
     var tempConnexion = factory.CreateConnection(); 
     tempConnexion.ConnectionString = ConnectionString; 
     tempConnexion.Open(); 
     var t = tempConnexion.BeginTransaction(IsolationLevel.ReadCommitted); 
     command = tempConnexion.CreateCommand(); 
     command.Connection = tempConnexion; 
     command.Transaction = t; 
    } 
    public MyCommand(string ConnectionString, DbProviderFactory factory, string requete) 
     : this(ConnectionString, factory) 
    { 
     command.CommandText = requete; 
    } 
    public MyCommand(string ConnectionString, string provider) 
     : this(ConnectionString, DbProviderFactories.GetFactory(provider)) { } 
    public MyCommand(string ConnectionString, string provider, string requete) 
     : this(ConnectionString, DbProviderFactories.GetFactory(provider), requete) { } 

    public static implicit operator DbCommand(myCommand c) 
    { 
     return c.command; 
    } 
    public void Dispose() 
    { 
     try 
     { 
      var t = command.Transaction; 
      if (t != null) 
      { 

       t.Commit(); 
       t.Dispose(); 
      } 
     } 
     catch { } 
     try 
     { 
      if (command.Connection != null) 
       command.Connection.Dispose(); 
      command.Dispose(); 
     } 
     catch { } 
    } 
    ~MyCommand() 
    { 
     if (command != null && command.Connection != null && command.Connection.State == ConnectionState.Open) 
      for (int i = 0; i < 2; i++)//twice to get the handle - it's working! 
       Dispose(); 
    } 
} 
+0

Ils me disaient toujours de ne pas utiliser '' Dispose' dans un destructor' – kevintjuh93

+1

utilisez "Using" ......... il va gérer tout – andy

+0

Il suffit d'implémenter l'interface 'IDiposable' pour supprimer les ressources. Voir http://stackoverflow.com/questions/456213/destructor-vs-idisposable –

Répondre

3

La connexion est fermée par la méthode Dispose non par le Destructeur.

Voir aussi la MSDN caution

Attention

Ne pas appeler Fermer ou Dispose sur une connexion, un DataReader, ou tout autre objet géré dans la méthode Finalize de votre classe. Dans un finaliseur , vous devez uniquement libérer des ressources non managées que votre classe possède directement. Si votre classe ne possède aucune ressource non managée, n'inclut pas une méthode Finalize dans votre définition de classe.

Une bien meilleure et méthode recommandée pour traiter la connexion est d'utiliser UTILISATION déclaration qui équivaut à dire comme

try 
{ 
    // your code 
} 
finally 
{ 
    myobject.Dispose(); 
} 
+0

oui. mais si j'oublie de disposer - le destructeur le disposera. –

+2

@chmouelkalifa Pourquoi oubliez-vous d'éliminer en premier lieu? Utilisez toujours les instructions 'using'. –

+0

pour la mise en garde - je sais, je me réfère à cela. mais ça marche quand même. Je dois juste le jeter deux fois. Pourquoi ne pas le faire? –