Sid*_*and 6 c# com garbage-collection
有关释放COM对象和垃圾收集的SO有很多问题,但我没有找到具体解决这个问题的任何问题.
在释放COM对象(在本例中特别是Excel Interop)时,我应该以什么顺序释放引用并调用垃圾收集?
在某些地方(比如这里),我看到了这个:
Marshall.FinalReleaseComObject(obj);
GC.Collect();
GC.WaitForPendingFinalizers();
Run Code Online (Sandbox Code Playgroud)
在其他人(如这里)这:
GC.Collect();
GC.WaitForPendingFinalizers();
Marshall.FinalReleaseComObject(obj);
Run Code Online (Sandbox Code Playgroud)
或者不重要,我什么都不担心?
Marshal.FinalReleaseComObject() 释放底层 COM 接口指针。
GC.Collect() 和 GC.WaitForPendingFinalizers() 导致调用 COM 包装器的终结器,该终结器调用 FinalReleaseComObject()。
因此,双管齐下是没有意义的。选择其中之一。
显式调用 FinalReleaseComObject() 的问题在于,只有当您为所有接口指针调用它时,它才会起作用。如果您只错过其中一个,Office 程序将继续运行。这很容易做到,特别是 C# 版本 4 中允许的语法糖使其成为可能。类似 的表达式range = sheet.Cells[1, 1]在 Excel 互操作代码中非常常见。那里有一个隐藏的 Range 接口引用,您永远不会显式地将其存储在任何地方。所以你也不能释放它。
这不是 GC.Collect() 的问题,它可以看到它们。然而,它也并非完全没有问题,只有当您的程序不再引用该接口时,它才会收集并运行终结器。这绝对是你的第二个片段的问题所在。当您调试程序时,往往会出错,调试器将本地对象引用的生命周期延长到方法的末尾。还有你看着Taskmgr并大喊“该死的!”的时候。
GC.Collect() 的通常建议也适用于此。保持程序运行并执行工作。正常情况下,您将触发垃圾收集并释放 COM 包装器。Office 程序将退出。它只是不会立即发生,它最终会发生。
| 归档时间: |
|
| 查看次数: |
657 次 |
| 最近记录: |