2009-06-20 7 views
-1

J'ai une fuite de mémoire dans mon code C# J'ai une classe avec des champs SqlCommand à l'intérieur. J'ai également une méthode publique Initialize() qui alloue ces champs SqlCommands. Avant l'allocation je vérifie (dans le code Initialize) si ce n'est pas la première fois que je fais l'allocation (ie pas la première fois que Initialize est appelée) et si ce n'est pas la première fois j'appelle Dispose sur les SqlCommands, et il semble causer une fuite de mémoire ....Question sur la fuite de mémoire dans .NET

Maintenant, il est important de mentionner que tous les SqlCommands utilisent la même SqlConnection et cette connexion est vivante pendant toute la vie du programme. La connexion est accessible via une propriété statique de classe statique ... (appelons-le ConnectionManager)

Une idée de ce qui pourrait être le problème? Merci!

+0

Je pense que vous devez fournir plus d'informations/un exemple de code – RichardOD

+3

Comment savez-vous qu'il y a une fuite de mémoire? –

Répondre

6

Krembo, la méthode recommandée pour utiliser des objets SqlConnection et SqlCommand est dans une instruction en utilisant, comme dans cet exemple de code de MSDN:

using (SqlConnection connection = new SqlConnection(connectionString)) 
{ 
    connection.Open(); 
    // Do work here; connection closed on following line. 
} 

Vous devriez probablement vous débarrasser de votre objet SqlConnection dès que vous » J'ai fini de l'utiliser, alors qu'il pourrait sembler que ce serait lent, dans les coulisses, la mise en commun des connexions permettra d'éliminer la plupart des frais généraux.

2

Vous devriez probablement publier une partie du code pertinent. Sans cela, je devine juste. Cependant, voici une estimation:

Vous suivez le mauvais modèle ici. Puisque votre classe maintient des objets qui implémentent IDisposable, votre classe devrait implémenter IDisposable elle-même. Vos correspondants doivent alors être modifiés pour appeler votre méthode de classe Éliminez quand ils sont fait avec elle:

using System; 
using System.Data.SqlClient; 

public static class ConnectionManager 
{ 
    private static readonly SqlConnection _connection = 
     new SqlConnection("connectionString"); 
    public static SqlConnection Connection { get { return _connection; } } 
} 

public class HoldsCommands : IDisposable 
{ 
    private readonly SqlCommand _commandOne = new SqlCommand("Command1"); 
    private readonly SqlCommand _commandTwo = new SqlCommand("Command2"); 

    public void DoSomethingWithAConnection() 
    { 
    } 

    public void Dispose() 
    { 
     if (_commandOne != null) 
     { 
      try 
      { 
       _commandOne.Dispose(); 
      } 
      catch (Exception) 
      { 
      } 
     } 

     if (_commandTwo != null) 
     { 
      try 
      { 
       _commandTwo.Dispose(); 
      } 
      catch (Exception) 
      { 
      } 
     } 
    } 
} 

Votre appelant alors vous appeler comme ceci:

using (var commands = new HoldsCommands()) { 
    commands.DoSomethingWithAConnection(); 
} 

Comme dit Luke Girvin, vous avez probablement vous n'avez pas besoin de la classe statique ConnectionManager si vous essayez simplement d'économiser sur les connexions à la base de données. .NET gère cela pour vous.