发布Excel COM对象

时间:2015-04-30 03:48:11

标签: c# com-interop excel-addins excel-automation

我有一些使用Excel COM对象的Excel自动化代码。从other SO posts开始,我知道应该尽快释放对象:

Excel.Range rng = GetSomeRange();

// do something with rng...

Marshal.ReleaseComObject(rng);

但是,如果我循环一个范围内的单元格,以下是正确的过程吗?

Excel.Range rng = GetSomeRange();
foreach (Excel.Range r in rng)
{
    // do something with r
    Marshal.ReleaseComObject(r); // release at earliest possible convenience
}

Marshal.ReleaseComObject(rng);

我在此不确定的是,如果我在r中释放每个rng,然后我也会释放rng,我会有效地释放rng两次或正确地将其他参考r正确发布到rngrng本身?

先谢谢!

修改

我选择了后一种策略:

Excel.Range rng = GetSomeRange();
foreach (Excel.Range r in rng)
{
    // do something with r
    Marshal.ReleaseComObject(r); // release at earliest possible convenience
}

Marshal.ReleaseComObject(rng);

显着减少了记忆......

再次 - 感谢所有人!

1 个答案:

答案 0 :(得分:5)

不幸的是,有很多虚假信息浮出水面。 首先让我清楚地说明答案:

您无需在大多数情况下致电Marshal.ReleaseComObject。为什么?因为垃圾收集器会为你做。 *请注意,我说大多数,您可能会发现保留许多引用会导致问题(无论出于何种原因)。仅在这些情况下,您是否应该致电Marshal.ReleaseComObject

Reference

  

Kristofer,我们总是为COM对象提供自动发布功能   GC确定需要清理它们。他们没有得到清理   立即,但在GC或之后的某个时刻确实得到清理   二。我已经向团队证实了这一点。

     他们说:

     

在博客中的应用程序类型中并不重要,如果人们搞砸了他们的应用程序会失败并且他们会得到明显的重新计数   错误。如果他们的代码在办公室内部加载,   而不是相反,它更令人担忧,因为   你可以最终释放别人的参考,然后就可以了   他们在代码中没有注意到但却打破了别人的问题   办公室加载项。

     

所以,重点是虽然ReleaseComObject更具确定性,   通常没有必要,因为GC会做同样的事情。

另外,我建议你阅读Marshal.ReleaseComObject Considered Dangerous

  

如果你想要调用“Marshal.ReleaseComObject”,你能100%   确定没有其他托管代码仍然可以访问RCW?如果   回答是“不”,然后不要打电话给它。最安全(和最安静)的建议是   完全避免Marshal.ReleaseComObject在一个系统中   组件可以随着时间的推移重复使用和版本化。

现在,您可能需要确定性地释放这些COM对象,但在大多数情况下,您可以删除所有Marshal.ReleaseComObject次调用。