gpt4 book ai didi

c# - 我可以清楚地了解 ReleaseComObject 吗?我可以忽略它吗?

转载 作者:太空狗 更新时间:2023-10-29 21:57:46 27 4
gpt4 key购买 nike

我已经在 VBA 中开发办公解决方案一段时间了,并且对 VBA 中的办公开发有相当完整的了解。我决定是时候用 .Net 学习一些真正的编程了,但我遇到了一些初期问题。

浏览了一堆文章和论坛(这里和其他地方),似乎有一些关于使用 COM 对象时在 .Net 中进行内存管理的混合信息。

有些人说我应该始终确定性地释放 COM 对象,而其他人则说我几乎不应该这样做。

人们说我应该这样做:

The book 'Professional Excel Development'第 861 页。

This stack exchange question已回答说“必须释放对 COM 对象的每个引用。如果不这样做,进程将保留在内存中”

This blog建议使用它解决他的问题。

人们说我不应该这样做:

This MSDN blog by Eric Carter声明“在 VSTO 方案中,您通常不必使用 ReleaseCOMObject。”

The book 'VSTO for Office 2007'由 Eric Carter 合着的文章似乎没有提及任何内存管理或 ReleaseComObject。

This MSDN blog by Paul Harrington说不要这样做。

意见不一的人:

Jake Ginnivan说我应该始终对不离开方法范围的 COM 对象执行此操作。如果 COM 对象离开了方法作用域,那么就不要管它了。为什么我不能一直忘记它呢?

Paul Harrington 的博客似乎表明 MS 的建议在过去的某个时间发生了变化。调用 ReleaseCOMObject 曾经是最佳实践但现在不是了吗?我可以将内存管理的更精细细节留给 MS 并假设一切都会好起来吗?

最佳答案

我在关于 ReleaseComObject 的互操作开发中尝试遵守以下规则。

如果我的托管对象实现某种类似于 IDisposable 的关闭协议(protocol),我会在我持有引用的任何子 COM 对象上调用 ReleaseComObject。我正在谈论的关闭协议(protocol)的一些示例:

  • IObjectWithSite.SetSite(null)
  • IOleObject.SetClientSite(null)
  • IOleObject.Close()
  • IDTExtensibility2.OnDisconnection
  • IDTExtensibility2.OnBeginShutdown

  • IDisposable.Dispose 本身

这有助于打破 .NET 和 native COM 对象之间潜在的循环引用,因此托管垃圾收集器可以畅通无阻地完成其工作。

也许,有一些类似的东西可以用在你的 VSTO 互操作场景中(AFAIR,IDTExtensibility2 在那里是相关的)。

如果互操作场景涉及 IPC COM 调用(例如,当您将托管事件接收器对象传递给 Excel 等进程外 COM 服务器时),还有另一个选项可以跟踪对托管对象的外部引用:IExternalConnection interface . IExternalConnection::AddConnection/ReleaseConnectionIUnknown::AddRef/Release 非常相似,但它们在以下情况下被调用从另一个 COM 单元(包括驻留在单独进程中的单元)添加引用。

IExternalConnection 提供了一种方法来为进程外场景实现几乎通用的关闭机制。当外部引用计数达到零时,您应该对您可能持有引用的任何外部 Excel 对象调用 ReleaseComObject,从而有效地打破进程和 Excel 进程之间任何潜在的循环 COM 引用。也许,像这样的东西已经由 VSTO 运行时实现了(我对 VSTO 的经验不多)。

也就是说,如果没有明确的关闭机制,我不会调用ReleaseComObject。另外,我从不使用 FinalReleaseComObject

关于c# - 我可以清楚地了解 ReleaseComObject 吗?我可以忽略它吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24330368/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com