2010-11-30 49 views
14

Voici le problème (potentiel):Ai-je besoin de libérer l'objet COM sur chaque itération 'foreach'?

Je crée un objet COM, puis utilise un 'foreach' pour parcourir chaque élément d'une collection qu'il renvoie. Ai-je besoin de relâcher chaque élément que je parcoure dans la collection? (Voir le code ci-dessous.) Si oui, je ne peux pas penser à un moyen de le libérer efficacement à partir d'une déclaration 'finally', juste au cas où il y aurait une erreur au cours de l'opération.

Des suggestions?

private static void doStuff() 
{ 
    ComObjectClass manager = null; 

    try 
    { 
     manager = new ComObjectClass(); 
     foreach (ComObject item in manager.GetCollectionOfItems()) 
     { 
      Log.Debug(item.Name); 
      releaseComObject(item); // <-- Do I need this line? 
            //  It isn't in a 'finally' block... 
            //    ...Possible memory leak? 
     } 
    } 
    catch (Exception) { } 
    finally 
    { 
     releaseComObject(manager); 
    } 
} 

private static void releaseComObject(object instance) 
{ 
    if (instance != null) 
    { 
     try 
     { 
      System.Runtime.InteropServices.Marshal.ReleaseComObject(instance); 
     } 
     catch 
     { 
      /* log potential memory leak */ 
      Log.Debug("Potential memory leak: Unable to release COM object."); 
     } 
     finally 
     { 
      instance = null; 
     } 
    } 
} 

Répondre

12

Vous ne devriez pas utiliser une instruction foreach avec un objet COM, comme une référence est faite dans les coulisses auxquelles vous avez aucun contrôle sur la libération. Je passer à une boucle for et assurez-vous never use two dots with COM objects.

La façon dont cela ressemblerait serait:

try 
{ 
    manager = new ComObjectClass(); 
    ComObject comObject = null; 
    ComObject[] collectionOfComItems = manager.GetCollectionOfItems(); 
    try 
    { 
     for(int i = 0; i < collectionOfComItems.Count; i++) 
     { 
      comObject = collectionOfComItems[i]; 
      ReleaseComObject(comObject); 
     } 
    }    
    finally 
    { 
     ReleaseComObject(comObject); 
    } 
} 
finally 
{ 
    ReleaseComObject(manager); 
} 
+0

Merci! C'est la réponse que je cherchais et je redoutais. – Matt

+0

Cela rendrait la boucle entière beaucoup plus lente, cependant. – nawfal

+0

@nawfal Pourquoi cela rendrait la boucle plus lente? –