2010-11-30 14 views
14

Aquí está el problema (potencial):¿Debo liberar el objeto COM en cada iteración 'foreach'?

Creo un objeto COM, y luego uso un 'foreach' para recorrer cada elemento de una colección que devuelve. ¿Debo liberar cada elemento individual al que repito en la colección? (Consulte el código a continuación.) Si es así, no puedo pensar en una forma efectiva de liberarlo desde una declaración 'finally', solo en caso de que haya un error a medida que se opera el elemento.

¿Alguna sugerencia?

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

Respuesta

12

No use una declaración foreach con un objeto COM, tal como se hace referencia en la sombra para el que no tiene control sobre la liberación. Me gustaría cambiar a un bucle for y asegúrese de que never use two dots with COM objects.

La forma en que esto se vería sería:

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

Gracias! Esa es la respuesta que estaba buscando y temiendo. – Matt

+0

Eso haría todo el ciclo mucho más lento, sin embargo. – nawfal

+0

@nawfal ¿Por qué esto haría que el ciclo fuera más lento? –

Cuestiones relacionadas