与Office(通常是Excel)一起使用COM Interop时,我总是小心地确保在每次引用时都拨打Marshal.ReleaseComObject
,以避免Excel无法退出的问题as described in this KB article。如何在Silverlight 4中释放COM对象
如何在使用OOB Silverlight应用程序中的Interop时(AutomationFactory.CreateObject
)确保Excel退出?
Silverlight没有Marshal.ReleaseComObject
方法,甚至拨打GC.Collect
和GC.WaitForPendingFinalizers
也没有帮助。
当然,Microsoft没有将此功能添加到Silverlight,而没有一种机制来释放COM引用?这对我来说似乎是自动化进程外COM服务器(如Excel)的不二之选。
一个令人惊讶的ommission,更何况作为皮特·布朗在他的著作“在行动的Silverlight 4”第5.5节竟把要说AutomationFactory.CreateObject
,即:
此功能的主要目的是允许自动化其他应用程序,包括Microsoft Office。
UPDATE回应汉斯的意见。
我不相信在典型的Office应用程序自动化中存在“无声刺客”问题。一个常见的用途可能类似于下面,我已经看到了的WinForms应用程序重复使用,而不需要通过不断来“毒害RCW”的文章由汉斯链接中描述:
- 创建Excel.Application实例
- 打开或创建一个工作簿
- 将数据写入到工作簿
- 显示Excel中,如果一切顺利的话,关闭工作簿,如果没有调用Application.Quit。
- 调用Marshal.ReleaseComObject释放所有Excel对象引用。
如Hans所推荐,未能调用Marshal.ReleaseComObject会导致运行Excel.exe的多个副本,如上面提到的知识库文章中所述 - 这是非常不理想的。
更新2
我使用瑞普这是由皮特·布朗的书的Silverlight 4在行动的源代码样本的样本,有此页面上的下载链接。示例解决方案AutomatingExcel位于Ch05.zip/5.03中。要瑞普:
- 确保没有Excel的实例在运行
- 运行AutomatingExcel样品
- Excel工作簿打开
- 关闭Excel
- 使用任务管理器观察到的Excel仍在运行。
将所有的动态变量设置为null并调用GC.Collect()似乎像在AnthonyWJones的答案中指出的那样工作。
更新2
宅男的答案是什么,我一直在寻找 - 通过在using语句的COM引用,而无需调用GC.Collect释放包裹引用。一些实验表明,与上面引用的知识库文章中描述的标准Marshal.ReleaseComObject
解决方案不同,它更容易处理每个单独的引用。
确切地说必须处理什么以确保所有Excel引用都已发布,这将是一件有趣的事情。
的可能重复的[?何时使用RelaseComObject VS FinalReleaseComObject](http://stackoverflow.com/ question/3937181/when-to-use-relasecomobject-vs-finalreleasecomobject) – 2011-04-09 13:28:36
@Hans:Silverlight在Marshal类中没有这些方法。 – AnthonyWJones 2011-04-09 13:57:35
@Anthony - 它解释了为什么这些方法都不是一个好主意。 “无声刺客”链接非常相关。 – 2011-04-09 14:01:10