[英]Do I need to release the COM object on every 'foreach' iteration?
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.我创建了一个 COM 对象,然后使用“foreach”来遍历它返回的集合中的每个元素。 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.您不应该对 COM 对象使用
foreach
语句,因为在幕后进行了引用,您无法控制释放。 I would switch to a for
loop and make sure you never use two dots with COM objects.我会切换到
for
循环并确保您永远不会在 COM 对象中使用两个点。
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);
}
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.我觉得这使您的代码更具可读性,尤其是当您需要多次迭代子项时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.