c# - 应该以什么顺序释放 COM 对象和垃圾收集?

标签 c# com garbage-collection

在 SO 上有很多关于释放 COM 对象和垃圾回收的问题,但我找不到具体解决这个问题的内容。

当释放 COM 对象(在这种情况下特别是 Excel Interop)时,我应该以什么顺序释放引用和调用垃圾回收?

在一些地方(比如 here )我看到了这个:

Marshall.FinalReleaseComObject(obj);
GC.Collect();
GC.WaitForPendingFinalizers();

而在其他(例如 here)中:

GC.Collect();
GC.WaitForPendingFinalizers();
Marshall.FinalReleaseComObject(obj);

或者这不重要,我什么都不担心?

最佳答案

Marshal.FinalReleaseComObject() 释放底层 COM 接口(interface)指针。

GC.Collect() 和 GC.WaitForPendingFinalizers() 导致调用 COM 包装器的终结器,它调用 FinalReleaseComObject()。

所以没有意义的是两种方式。选择一个或另一个。

显式调用 FinalReleaseComObject() 的问题在于,只有当您为所有 接口(interface)指针调用它时,它才会起作用。如果您只错过其中一个,Office 程序将继续运行。这非常很容易做到,尤其是 C# 版本 4 中允许的语法糖使它成为可能。类似 range = sheet.Cells[1, 1] 的表达式,在 Excel 互操作代码中非常常见。那里有一个隐藏的 Range 接口(interface)引用,您永远不会将其显式存储在任何地方。所以你也不能释放它。

这不是 GC.Collect() 的问题,它可以看到它们。然而,它也并非完全没有问题,它只会在您的程序不再引用该接口(interface)时收集并运行终结器。这绝对是你的第二个片段有什么问题。当你调试你的程序时往往会出错,调试器将本地对象引用的生命周期延长到方法的末尾。还有你看着 Taskmgr 大喊“去死!”的时候

GC.Collect() 的常用建议也适用于此。保持程序运行并执行工作。正常的事情会发生,您将触发垃圾收集并释放 COM 包装器。 Office 程序将退出。它不会立即发生,它最终会发生。

关于c# - 应该以什么顺序释放 COM 对象和垃圾收集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13572004/

相关文章:

c++ - 追踪 COM 接口(interface)/SysAlloc 泄漏

windows - 为什么我要使用 "Both"COM 线程模型而不是 "Free"?

Java GC - 有没有办法确定收集了哪些对象

garbage-collection - D 垃圾收集器是 "not guaranteed to run the destructor for all unreferenced objects"是什么意思?

c# - .NET (ApiController)/jQuery .ajax : what to return from POST?

c# - 在 C# 中将 uri 转换为字符串

c# - WPF - 触摸手势 - 滚动时抑制鼠标单击

c# - 将 C 套接字客户端连接到 C# 套接字服务器

c++ - OLE bstr 不以 null 终止?

c# - 未分配给变量的类实例是否会过早被垃圾回收?