Должен ли я освобождать объект 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;
}
}
}
Ответы
Ответ 1
Вы не должны использовать оператор foreach
с объектом COM, поскольку ссылка делается за кулисами, на которые у вас нет контроля над выпуском. Я бы переключился на цикл for
и убедитесь, что вы никогда не используете две точки со COM-объектами.
Как бы это выглядело:
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);
}