Here\'s the (potential) problem:
I create a COM object, and then use a \'foreach\' to iterate through each element in a collection it returns. Do I need to release
Another way is to create your own iterator function :
IEnumerable<ComObject> GetChildItems(this ComObjectClass manager) {
ComObject comObject = null;
ComObject[] collectionOfComItems = manager.GetCollectionOfItems();
for (int i = 0; i < collectionOfComItems.Length; i++) {
try {
comObject = collectionOfComItems[i];
yield return comObject;
} finally {
if (comObject != null)
Marshal.ReleaseComObject(comObject);
}
}
yield break;
}
private static void doStuff() {
ComObjectClass manager = null;
try {
manager = new ComObjectClass();
foreach (ComObject item in manager.GetChildItems()) {
Log.Debug(item.Name);
}
} finally {
releaseComObject(manager);
}
}
I feel this makes your code much more readable, especially if you need to iterate through the child items at multiple times.
You should not use a foreach
statement with a COM object, as a reference is made behind the scenes to which you have no control over releasing. I would switch to a for
loop and make sure you never use two dots with COM objects.
The way this would look would be:
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);
}