.net - 我什么时候需要调用 ReleaseComObject?

标签 .net com office-interop

在 Microsoft Office AddIn 中,我们在事件中传递 COM 对象。举一个具体的例子,当 Word 打开一个文档时,我们被调用并传递一个 Document 对象。那么我们什么时候需要调用 Marshal.ReleaseComObject() 呢?

  • 如果我们访问 Document 对象,是否需要对其调用 release ?或者我们可以假设 Word 已经访问过它并且会清理它吗?
  • 如果我们访问给我们一个字符串的 Document.Name。由于字符串不是 COM 对象,我们不需要清理它 - 对吗?
  • 但是,如果我们访问任何返回包装 COM 对象的类的成员(它是由成员方法/函数返回的任何类),我们确实需要在其上调用 release - 对吗?

  • 如果我们错过了发布会怎样?我们在不确定的时间内持有的任何 COM 对象都包含在我们的类中,并实现了 IDisposable。完成后我们调用 Dispose()。但是处理此问题的一些代码很复杂,我猜我们偶尔会遇到不调用 Dispose 的情况。

    我们是否最好有一个终结器,然后为这些对象的每个实例增加开销(很多!)?还是我们最好使用少量从未发布的 Word COM 对象?

    谢谢 - 戴夫

    最佳答案

    总之,您对 COM 对象的每个引用都必须被释放 .如果不这样做,该过程将保留在内存中。

    这不包括您没有明确引用的值类型(字符串等)和子 COM 对象。

    一种异常(exception)情况可能是作为事件参数传递给您的 COM 对象。我不认为你需要释放它们,但我不确定。然而,快速测试应该可以证实这一点。 (在释放和不释放 COM 对象的情况下尝试加载项。看看加载项是否开始变得有趣,或者在应用程序关闭后是否有任何相关进程仍在运行。)

    要解决您的具体问题:

  • 如果我们访问 Document 对象,是否需要对其调用 release ?或者我们可以假设 Word 已经访问过它并且会清理它吗? ——你必须释放它。
  • 如果我们访问给我们一个字符串的 Document.Name。由于字符串不是 COM 对象,我们不需要清理它 - 对吗? -- 您不需要清理值类型。
  • 但是,如果我们访问任何返回包装 COM 对象的类的成员(这是由成员方法/函数返回的任何类),我们确实需要调用 release - 对吗? -- 如果您没有明确引用它,则不需要发布它。 (有一些异常(exception)。例如在这个 question of mine 中,我发现一个特定的 COM 方法正在实例化一个 COM 对象并且从未释放它。由于我无法控制方法实现,我唯一的选择是避免使用该方法。)
  • 如果我们错过了发布会怎样? -- 进程(winword.exe、excel.exe 等)将保留在内存中。随着时间的推移,所有这些未终止的进程将耗尽机器上的所有可用内存。
  • 我们是否最好有一个终结器,然后为这些对象的每个实例增加开销(很多!)?还是我们最好使用少量从未发布的 Word COM 对象? -- 你最好使用终结器。始终释放您的 COM 对象!我发现步骤概述 here是最有效的。 (这些步骤使用 FinalReleaseComObject,它比 ReleaseComObject 更受欢迎。)我还建议不要终止 Office 进程作为不释放 COM 的替代方法。随着时间的推移,这将导致 Office 互操作性问题(我从未完全理解)。
  • 关于.net - 我什么时候需要调用 ReleaseComObject?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10473021/

    相关文章:

    c# - Visual Studio 插件显示资源文件中的文本而不是代码

    c++ - shell 扩展:IShellExtInit::Initialize 调用了 4 次

    c# - 使用 Microsoft.Office.Interop.Excel 导出时我是否正确关闭了 excel 文件

    c# - 引用的库未被复制

    .net - 如何在控制台应用程序中的 WPF MediaElement 上播放视频

    c# - 按照 MVVM 设计模式从 ViewModel 访问 this.content

    .net - 将 .NET SecureString 传递给 COM Interop

    c++ - 升级COM回调接口(interface)

    c# - RibbonDropDownItem 点击监听器

    c# - 查找所有打开的 Excel 工作簿