【问题标题】:Releasing Excel COM objects释放 Excel COM 对象
【发布时间】:2015-07-09 14:54:31
【问题描述】:

我有一些使用 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);

我在这里不确定的是,如果我在rng 中释放每个r,然后我还释放rng,我是有效地释放rng 两次还是正确地释放附加引用r 到@987654330 @ 和 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);

显着减少了内存...

再次感谢大家!

【问题讨论】:

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


【解决方案1】:

不幸的是,周围有很多虚假信息。 首先让我明确回答:

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

Reference:

Kristofer,我们一直都有 COM 对象的自动释放作为 GC 确定它需要清理它们。他们没有被清理干净 立即,但在 GC 或 二。我已经向团队确认了这一点。

他们说:

在博客中的应用类型中并不重要,如果人们搞砸了他们的应用程序将会失败并且他们会得到明显的引用计数 错误。如果他们的代码在办公室内加载, 而不是相反,它更令人担忧,因为 您最终可以发布其他人的参考,然后可以 他们在代码中没有注意到但破坏了其他人的问题 代替 office 插件。

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

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

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

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

【讨论】:

  • 很好的答案,谢谢@Jesse。在我的系统中,我每隔几秒钟创建一次 Range 对象,并且这些数量在一个会话中高达 ~100,000 个。作为一个结果,(我怀疑)我看到一个 Excel 内存占用有时超过 800Mb,这不可能是正确的 IMO。对于ReleaseComObject,我只在确定不再需要我的对象时才使用它。例如,当在范围内使用时,一旦超出范围就不再需要。是否有可能创建如此大量的对象会导致我所描述的大规模“泄漏”?再次感谢!
  • @PatMustard:如果您要创建那么多 Range 对象,那么内存使用量可能就是因为这个原因。你创造这么多是有原因的吗?例如,最好一口气阅读/更新。此外,您也可以尝试使用 GC.Collect(),但我会将其作为最后的手段。
  • 不幸的是,我需要这样做,因为我的工作表需要足够健壮,以处理运行时对范围的更改以响应不断变化的值等。我已经实现了后一种策略(释放参考组件@ 987654330@ 和 rng 本身,我看到内存消耗有了显着改善)。该表与实时刻度数据相关,所以我真的不想走 GC 路线。总而言之,现在情况有了很大改善 - 感谢您的建议......它有很大帮助:)
猜你喜欢
  • 2015-09-25
  • 2012-09-17
  • 2010-11-29
  • 1970-01-01
  • 1970-01-01
  • 2012-03-05
  • 2014-02-14
  • 1970-01-01
相关资源
最近更新 更多