需要澄清正确清理 Excel 互操作对象的答案

Posted

技术标签:

【中文标题】需要澄清正确清理 Excel 互操作对象的答案【英文标题】:Need Clarification On Answer For Cleaning Up Excel Interop Objects Properly 【发布时间】:2015-05-06 17:24:50 【问题描述】:

关于 Hans Passant 对这里问题的回答...Clean up Excel Interop Objects with IDisposable...

他让我意识到我不需要遵循两个点规则...声明所有 com 对象,以便在处理完它们后可以通过 Marshal.ReleaseComObject 释放它们。所以现在我明白我可以在我的 Excel 代码之后调用 GC.Collect 和 GC.WaitForPendingFinalizers 并且所有对象都将被正确释放。一方面,我认为这很好,并且会减少我在 c# 中编写的宏的长度,但我习惯于在使用完对象后立即释放对象,以最大限度地减少宏运行时的内存使用量。我应该关心清理对象,还是像汉斯建议的那样在宏末尾进行清理可以吗?我通常处理大文件,我的宏会创建许多 com 对象来完成一项任务。

【问题讨论】:

【参考方案1】:

我习惯于在使用完对象后立即释放它们,以在宏运行时最大限度地减少内存使用。我应该关心清理对象,还是可以像 Hans 建议的那样在宏末尾进行清理?

作为一般规则,一旦您完成任何资源,请立即释放它。资源越昂贵和/或稀缺,它就变得越重要。数据库连接、内存、文件句柄等都是如此。

它也适用于对 COM 对象的引用。

话虽如此,表演

GC.Collect();
GC.WaitForPendingFinalizers();

为了发布您的 as-soon-as-feas-feasible cleanup 可能捕获的任何引用是明智的做法。

有一个相反的论点可以提出,您可以使用常识并查看自己的情况来应用它。您最终会编写更多代码来清理每个 COM 引用。如果您在达到可以清理的点之前没有创建过多的 COM 对象,则可能值得选择更简单的代码(例如使用双点),因为您知道您暂时消耗的资源比您绝对需要的要多.

【讨论】:

好吧,我当然不会推荐在每隔一行之后手动 GC.Collect()。当您完成重要的互操作操作(例如,打开文档、查找工作表、遍历一堆行、释放文档,然后执行 GC.Collect() 和 GC.WaitForPendingFinalizers( ))

以上是关于需要澄清正确清理 Excel 互操作对象的答案的主要内容,如果未能解决你的问题,请参考以下文章

COM 互操作 (CCW) 中的重载 - IDispatch 名称包括后缀(_2、_3 等)

Windows 服务未启动 - Excel - 邮件互操作

C# Excel 互操作合并不起作用

LLVM 互操作性(如 JVM 或 .Net)- 有可能吗?

excel 互操作:NumberFormat #,##0.000 不显示预期结果

使用 CSC 编译 C# 代码 - excel 互操作