我需要在每个'foreach'迭代释放COM对象吗? [英] Do I need to release the COM object on every 'foreach' iteration?

查看:168
本文介绍了我需要在每个'foreach'迭代释放COM对象吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是(潜在的)问题:



我创建一个COM对象,然后使用一个foreach遍历它返回的集合中的每个元素。我需要释放在集合中迭代的每个单独的元素吗? (见下面的代码。)如果是这样,我不能想办法有效地从一个'finally'语句中释放它,只是为了在项目被操作时出现错误。



有任何建议吗?

  private static void doStuff()
{
ComObjectClass manager = null;

try
{
manager = new ComObjectClass();
foreach(manager.GetCollectionOfItems()中的ComObject项)
{
Log.Debug(item.Name);
releaseComObject(item); //< - 我需要这行吗?
//它不在一个'finally'块...
// ...可能的内存泄漏?
}
}
catch(Exception){}
finally
{
releaseComObject(manager);
}
}

private static void releaseComObject(object instance)
{
if(instance!= null)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(instance);
}
catch
{
/ * log潜在内存泄漏* /
Log.Debug(潜在内存泄漏:无法释放COM对象。
}
finally
{
instance = null;
}
}
}


解决方案>

你不应该使用带有COM对象的 foreach 语句,因为引用是在你没有控制释放的场景之后。我将切换到 for 循环,并确保您从不使用两个点与COM对象。



这样看起来将是:

  try 
{
manager = new ComObjectClass();
ComObject comObject = null;
ComObject [] collectionOfComItems = manager.GetCollectionOfItems();
try
{
for(int i = 0; i {
comObject = collectionOfComItems [i];
ReleaseComObject(comObject);
}
}
finally
{
ReleaseComObject(comObject);
}
}
finally
{
ReleaseComObject(manager);
}


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 each individual element I iterate through in the collection? (See code below.) If so, I can't think of a way to effectively to release it from within a 'finally' statement, just in case there is an error as the item is being operated upon.

Any suggestions?

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

解决方案

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

这篇关于我需要在每个'foreach'迭代释放COM对象吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆