c# - 释放 Excel COM 对象

标签 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);

我不确定的是,如果我在 rng 中释放每个 r 然后我也释放 rng 我是否有效释放rng 两次或正确释放附加引用 rrngrng 本身?

谢谢你!

编辑

我选择了后一种策略:

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

显着减少了内存...

再次感谢大家!

最佳答案

不幸的是,到处都是很多虚假信息。 先把答案说清楚:

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

Reference :

Kristofer, we’ve always had automatic releases for COM objects as the GC determines it needs to clean them up. They don’t get cleaned up immediately, but do get cleaned up at some point later after a GC or two. I've confirmed with this with the team.

They said:

In the type of app in the blog it doesn’t really matter, if people screw up their app will fail and they’ll get obvious ref-counting bugs. In cases where their code is being loaded inside of office, rather than the other way around, it is much more concerning because you can end up releasing someone else’s reference then there can be problems that they don’t notice in their code but breaks someone elses office add-in instead.

So, the point is that while ReleaseComObject is more deterministic, it's usually not necessary as the GC will do the same thing.

此外,我建议您阅读 Marshal.ReleaseComObject Considered Dangerous .

If you’re tempted to call “Marshal.ReleaseComObject”, can you be 100% certain that no other managed code still has access to the RCW? If the answer is ‘no’, then don’t call it. The safest (and sanest) advice is to avoid Marshal.ReleaseComObject entirely in a system where components can be re-used and versioned over time.

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

关于c# - 释放 Excel COM 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29958679/

相关文章:

c# - 从数据库中转换空日期时间值?

c# - 如何等待异步完成?

c# - 如何在 C# 中从 System.Drawing.Color 转换为 Excel.ColorFormat?更改评论颜色

c# - 打开 InputBox 时 Excel 无响应,c#

c# - 为 COM Interop 公开 dll

javascript - 使用 Office.js 合并 Excel 单元格

c# - 将内部类注入(inject) Azure WebJob 函数

c# - 通过示例学习 - 术语(?,:, 等)

.net - 通过 COM 互操作调用时,Type.GetType 返回 null

c# - 什么时候需要/适合使用 InAttribute 和 OutAttribute 进行 COM Interop