2010-11-30 2 views
14

Вот проблема (потенциал):Должен ли я освобождать объект COM на каждой итерации foreach?

Я создаю COM-объект, а затем использую «foreach» для итерации по каждому элементу в возвращаемой коллекции. Нужно ли мне выпускать каждый отдельный элемент, который я повторяю в коллекции? (См. Код ниже.) Если это так, я не могу придумать, как эффективно его освободить из выражения «finally», только в случае возникновения ошибки при работе элемента.

Любые предложения?

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

ответ

12

Вы не должны использовать foreach заявление с COM-объекта, как ссылка за кулисами, на которые вы имеете никакого контроля над отпуская. Я хотел бы перейти к for петли и убедитесь, что вы never use two dots with COM objects.

Путь это будет выглядеть бы:

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

Спасибо! Это ответ, который я искал и боялся. – Matt 2010-11-30 20:00:29

Смежные вопросы