Marshal.ReleaseComObject
,以避免Excel不退出的问题,如此KB文章中所述。当我从OOB Silverlight应用程序(使用
AutomationFactory.CreateObject
)使用Interop时,如何确保Excel退出?Silverlight没有
Marshal.ReleaseComObject
方法,即使调用GC.Collect
和GC.WaitForPendingFinalizers
也无济于事。毫无疑问,Microsoft没有添加此功能到Silverlight而没有释放COM引用的机制?对于自动化外部进程的COM服务器(例如Excel),这对我来说似乎是一个停滞不前的问题。
这是一个令人惊讶的省略,尤其是Pete Brown在他的书“Silverlight 4 in Action”的第5.5节中甚至如此说:
AutomationFactory.CreateObject
:
更新:作为对Hans评论的回应。此功能的主要目的是允许自动化其他应用程序,包括Microsoft Office。
我不确定“无声刺客”问题是否存在于Office应用程序的典型自动化中。常见用法可能看起来像以下内容,我在WinForms应用程序中反复看到过这种用法,从未遇到过Hans链接的文章中描述的“毒害RCW”:
- 创建一个Excel.Application实例
- 打开或创建工作簿
- 将数据写入工作簿
- 如果一切顺利,则显示Excel,关闭工作簿并调用Application.Quit。
- 调用Marshal.ReleaseComObject以释放所有Excel对象引用。
更新2:
我用于重现此问题的示例是Pete Brown的书“Silverlight 4 in Action”的源代码示例,此页面上有下载链接。示例解决方案AutomatingExcel在Ch05.zip / 5.03中。要重现:
- 确保没有Excel实例正在运行
- 运行AutomatingExcel示例
- 打开了一个Excel工作簿
- 关闭Excel
- 使用任务管理器观察Excel仍在运行。
Otaku的回答是我所需要的——通过在using语句中包装引用,COM引用将被释放,无需调用GC.Collect。经过一些实验表明,与上面引用的KB文章中描述的标准的Marshal.ReleaseComObject解决方案相比,它更容易处理未能正确处置每个引用的情况。
有一个权威的看法,确切地说明必须处置哪些内容才能确保所有Excel引用都被释放,这将是很有趣的。
Marshal
类中没有这两种方法。 - AnthonyWJones