2010-11-30 9 views
14

Hier ist das (potentielle) Problem:Muss ich das COM-Objekt bei jeder 'foreach'-Iteration freigeben?

Ich erstelle ein COM-Objekt, und verwenden Sie dann eine 'foreach', um jedes Element in einer Sammlung durchlaufen, die es zurückgibt. Muss ich jedes einzelne Element freigeben, das ich in der Sammlung durchlaufen habe? (Siehe Code unten.) Wenn das der Fall ist, kann ich mir keinen Weg vorstellen, ihn effektiv aus einer 'finally'-Anweisung zu entfernen, nur für den Fall, dass ein Fehler auftritt, während der Gegenstand bearbeitet wird.

Irgendwelche Vorschläge?

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; 
     } 
    } 
} 

Antwort

12

Sie sollten keine foreach Anweisung mit einem COM-Objekt verwenden, als eine Referenz hinter den Kulissen gemacht wird, auf die Sie über die Freigabe keine Kontrolle haben. Ich würde wechseln Sie zu einem for Schleife und stellen Sie sicher, dass Sie never use two dots with COM objects.

Die Art und Weise dies wäre aussehen würde:

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

Thank you! Das ist die Antwort, nach der ich gesucht habe, und ich fürchte mich. – Matt

+0

Das würde jedoch die ganze Schleife viel langsamer machen. – nawfal

+0

@nawfal Warum würde das die Schleife langsamer machen? –