关于释放 COM 对象和垃圾收集,有很多问题,但我找不到专门解决这个问题的东西。
当释放 COM 对象(在本例中具体为 Excel Interop)时,我应该按什么顺序释放引用并调用垃圾回收?
在某些地方(例如here https://stackoverflow.com/a/1893653/976080)我见过这个:
Marshall.FinalReleaseComObject(obj);
GC.Collect();
GC.WaitForPendingFinalizers();
而在其他方面(例如here https://stackoverflow.com/a/159419/976080) this:
GC.Collect();
GC.WaitForPendingFinalizers();
Marshall.FinalReleaseComObject(obj);
或者这并不重要,我什么也不担心?
Marshal.FinalReleaseComObject() 释放底层 COM 接口指针。
GC.Collect() 和 GC.WaitForPendingFinalizers() 导致调用 COM 包装器的终结器,该终结器调用 FinalReleaseComObject()。
所以没有意义的是去做both方法。选择其中之一。
显式调用 FinalReleaseComObject() 的麻烦在于,它仅在您调用它时才起作用all接口指针。如果您只错过其中一个,Office 程序将继续运行。那是very很容易做到,特别是 C# 版本 4 中允许的语法糖使其成为可能。像这样的表达range = sheet.Cells[1, 1]
,在 Excel 互操作代码中非常常见。那里有一个隐藏的 Range 接口引用,您永远不会显式地将其存储在任何地方。所以你也不能释放它。
这不是 GC.Collect() 的问题,它可以看到它们。然而,它也并非完全没有问题,只有当您的程序不再引用该接口时,它才会收集并运行终结器。这绝对是你的第二个片段的问题所在。当您调试程序时,往往会出错,调试器将本地对象引用的生命周期延长到方法的末尾。还有你看着Taskmgr并大喊“该死的!”的时候。
GC.Collect() 的通常建议也适用于此。保持程序运行并执行工作。正常情况下,您将触发垃圾收集并释放 COM 包装器。 Office 程序将退出。它只是不会立即发生,它最终会发生。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)