Dav*_*len 8 .net com office-interop
在Microsoft Office AddIn中,我们在事件中传递COM对象.举一个特定的情况,当Word打开一个文档时,我们被调用并传递一个Document对象.那么我们什么时候需要调用Marshal.ReleaseComObject()?
如果我们错过了发布会怎么样?我们持有的任何COM对象在不确定的时间内包含在我们的类中,并且实现了IDisposable.我们完成后调用Dispose().但是处理这个问题的一些代码很复杂,我猜我们偶尔会遇到一个不调用Dispose的情况.
我们最好有一个终结器,然后为这些对象的每个实例增加开销(很多!)?或者我们最好使用少量从未发布的Word COM对象?
谢谢 - 戴夫
简而言之,您对 COM 对象所做的每个引用都必须被释放。如果不这样做,该过程将保留在内存中。
这不包括您未显式引用的值类型(字符串等)和子 COM 对象。
一种例外可能是作为事件参数传递给您的 COM 对象。我认为你不需要释放它们,但我不确定。然而,快速测试应该可以证实这一点。(在释放或不释放 COM 对象的情况下尝试您的外接程序。看看外接程序是否开始表现得很有趣,或者在应用程序关闭后是否有任何相关进程仍在运行。)
为了解决您的具体问题:
如果我们访问 Document 对象,是否需要对其调用release?或者我们可以假设 Word 已经访问了它并且会清理它吗?——你必须释放它。
如果我们访问 Document.Name,它会给我们一个字符串。由于字符串不是 COM 对象,我们不需要清理它 - 对吗?-- 您不需要清理值类型。
但是,如果我们访问任何返回包装 COM 对象的类的成员(这是由成员方法/函数返回的任何类),我们确实需要对其调用release - 对吗?-- 如果您没有明确引用它,则不需要释放它。(也有一些例外。例如,在我的这个问题中,我发现一个特定的 COM 方法正在实例化一个 COM 对象并且从未释放它。由于我无法控制方法实现,所以我唯一的选择是避免使用该方法。)
如果我们错过了发布会怎样?-- 进程(winword.exe、excel.exe 等)将保留在内存中。随着时间的推移,所有这些未终止的进程将耗尽机器上的所有可用内存。
我们是否最好拥有一个终结器,然后为这些对象的每个实例增加开销(很多!)?或者我们使用少量从未释放的 Word COM 对象是否会更好?-- 你最好使用终结器。始终释放您的 COM 对象!我发现此处概述的步骤是最有效的。(这些步骤使用 FinalReleaseComObject,它优于 ReleaseComObject。)我还建议不要终止 Office 进程作为不释放 COM 的替代方法。随着时间的推移,这将导致 Office 互操作出现问题(我从未完全理解)。
| 归档时间: |
|
| 查看次数: |
1903 次 |
| 最近记录: |