如何在Silverlight 4中释放COM对象 [英] How to release COM objects in Silverlight 4

查看:255
本文介绍了如何在Silverlight 4中释放COM对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当使用COM Interop with Office(通常是Excel)时,我总是小心确保我在每个引用上调用 Marshal.ReleaseComObject ,以避免Excel不退出的问题,如本知识库文章所述。



当我从OOB Silverlight应用程序(使用 AutomationFactory.CreateObject )使用Interop时,如何确保Excel退出?



Silverlight没有 Marshal.ReleaseComObject 方法,甚至调用 GC.Collect



当然,Microsoft没有将此功能添加到Silverlight,而没有释放COM引用的机制。对我来说,这似乎是一个showstopper自动化进程外COM服务器,如Excel。



令人惊讶的ommission,更是如此的Pete布朗在5.5节他的书Silverlight 4 in Action中对 AutomationFactory.CreateObject 的说法是:


此功能的主要目的是允许其他应用程序(包括Microsoft Office)的自动化。


更新以回应汉斯的评论。



我不相信沉默刺客问题存在于Office应用程序的典型自动化中。一个常见的用法可能看起来像下面,我已经看到在WinForms应用程序中反复使用,没有遇到过由Hans链接的文章中描述的中毒的RCW:




  • 创建Excel.Application实例

  • 打开或创建工作簿

  • 将数据写入工作簿

  • 显示Excel,如果一切顺利,关闭工作簿,如果没有,调用Application.Quit。

  • 调用Marshal.ReleaseComObject释放所有Excel对象引用。 li>


如果Hans不推荐调用Marshal.ReleaseComObject,将会保留Excel.exe运行的多个副本,非常不受欢迎。



UPDATE 2



这是从Pete Brown的书Silverlight 4的源代码中的一个示例,在这个页面上有一个下载链接。样品溶液AutomatingExcel在Ch05.zip / 5.03中。要重现:




  • 确保没有运行Excel实例

  • 运行AutomatingExcel示例

  • 打开Excel工作簿

  • 关闭Excel

  • 使用任务管理器观察Excel仍在运行。



将所有动态变量设置为null并调用GC.Collect()似乎像AnthonyWJones的答案中所指出的那样工作。



UPDATE 2



Otaku的答案就是我要找的 - 在using语句中引用COM引用被释放,而不需要调用GC.Collect。有些实验表明,与上面引用的知识库文章中描述的标准 Marshal.ReleaseComObject 解决方案不同,它更能容忍无法处理每个引用。

$

b
$ b

这是非常有趣的,有一个权威取得必须处理,以确保所有的Excel参考。解决方案

您可以实现 IDisposable 界面。我看到的最好的例子是 http://csfun.blog49。 fc2.com/blog-entry-79.html 。博客条目是日语,但是在Chrome中打开,如果您不阅读日语,则允许Google为您翻译页面。



此外,如果您只想要源代码示例的COM包装器直接可以下载它的示例应用程序: SilverOffice


When using COM Interop with Office (usually Excel), I always carefully ensure I call Marshal.ReleaseComObject on every reference, to avoid the problem where Excel doesn't quit as described in this KB article.

How can I ensure Excel quits when I use Interop from an OOB Silverlight application (with AutomationFactory.CreateObject)?

Silverlight doesn't have a Marshal.ReleaseComObject method and even calling GC.Collect and GC.WaitForPendingFinalizers doesn't help.

Surely Microsoft hasn't added this feature to Silverlight without a mechanism to release COM references? This seems to me to be a showstopper for automating out-of-process COM servers such as Excel.

A surprising ommission, all the more so as Pete Brown in section 5.5 of his book "Silverlight 4 in Action" goes as far as to say about AutomationFactory.CreateObject, that:

The primary intent of this feature is to allow automation of other applications, including Microsoft Office.

UPDATE in response to Hans' comments.

I'm not convinced the "silent assassin" problem exists in typical automation of Office apps. A common use might look something like the following, which I've seen used repeatedly in WinForms applications without ever coming across the "poisoned RCW" described in the article linked by Hans:

  • Create an Excel.Application instance
  • Open or create a workbook
  • Write data to the workbook
  • Show Excel if all went well, close the workbook and call Application.Quit if not.
  • Call Marshal.ReleaseComObject to release all Excel object references.

Failing to call Marshal.ReleaseComObject as recommended by Hans will leave multiple copies of Excel.exe running, as described in the KB article mentioned above - highly undesirable.

UPDATE 2

The sample I'm using to repro this is a sample from the source code for Pete Brown's book Silverlight 4 in action, there's a download link on this page. The sample solution AutomatingExcel is in Ch05.zip / 5.03. To repro:

  • Make sure no instances of Excel are running
  • Run AutomatingExcel sample
  • An Excel workbook is opened
  • Close Excel
  • Observe with Task Manager that Excel is still running.

Setting all the dynamic variables to null and calling GC.Collect() seems to work as pointed out in AnthonyWJones's answer.

UPDATE 2

Otaku's answer is what I was looking for - by wrapping references in a using statement the COM references are released without the need to call GC.Collect. A bit of experimentation shows that it's more tolerant of failing to dispose every single reference, unlike the standard Marshal.ReleaseComObject solution described in the KB article referenced above.

It would be interesting to have an authoritative take on exactly what must be disposed to ensure that all Excel references are released.

解决方案

You could implement the IDisposable interface. The best example of this I've seen is at http://csfun.blog49.fc2.com/blog-entry-79.html. The blog entry is in Japanese, but open in Chrome and let Google do the page translation for you if you don't read Japanese.

Also, if you just want the source code example of the COM wrapper directly you can download the sample app it comes in: SilverOffice.

这篇关于如何在Silverlight 4中释放COM对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆