我有一些使用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
正确发布到rng
和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);
显着减少了记忆......
再次 - 感谢所有人!
答案 0 :(得分:5)
不幸的是,有很多虚假信息浮出水面。 首先让我清楚地说明答案:
您无需在大多数情况下致电Marshal.ReleaseComObject
。为什么?因为垃圾收集器会为你做。
*请注意,我说大多数,您可能会发现保留许多引用会导致问题(无论出于何种原因)。仅在这些情况下,您是否应该致电Marshal.ReleaseComObject
。
Kristofer,我们总是为COM对象提供自动发布功能 GC确定需要清理它们。他们没有得到清理 立即,但在GC或之后的某个时刻确实得到清理 二。我已经向团队证实了这一点。
他们说:在博客中的应用程序类型中并不重要,如果人们搞砸了他们的应用程序会失败并且他们会得到明显的重新计数 错误。如果他们的代码在办公室内部加载, 而不是相反,它更令人担忧,因为 你可以最终释放别人的参考,然后就可以了 他们在代码中没有注意到但却打破了别人的问题 办公室加载项。
所以,重点是虽然ReleaseComObject更具确定性, 通常没有必要,因为GC会做同样的事情。
另外,我建议你阅读Marshal.ReleaseComObject Considered Dangerous。
如果你想要调用“Marshal.ReleaseComObject”,你能100% 确定没有其他托管代码仍然可以访问RCW?如果 回答是“不”,然后不要打电话给它。最安全(和最安静)的建议是 完全避免Marshal.ReleaseComObject在一个系统中 组件可以随着时间的推移重复使用和版本化。
现在,您可能需要确定性地释放这些COM对象,但在大多数情况下,您可以删除所有Marshal.ReleaseComObject
次调用。