我基本上了解托管RCW对象如何在.NET中包装COM对象。我的问题是当COM对象不复存在时会发生什么。我知道RCW对象会增加引用计数,因此只要RCW对象处于活动状态,就不应释放COM对象。但是,如果从用户的角度来看删除了 ,该怎么办?
假设我在PowerPoint中有一个形状,Excel中的工作表或Word段落。我的应用程序创建了一个引用并保留了一段时间。
用户现在可以删除PowerPoint幻灯片,关闭Excel文件或删除Word段落。检测此问题的正确方法是什么?
尝试一下,建议COM对象在访问任何属性时抛出一个COMException
错误代码0x80004005,说对象不存在。
但我想知道:这是一种可靠且安全的方法吗? COM对象是否真的与RCW对象保持一致,或Office可以将其从内存中删除?在这种情况下,使用悬挂参考是不是很危险,是否有更好的方法?
答案 0 :(得分:3)
你在做什么本身就有风险。在用户与Office程序交互时使用自动化非常棘手,您必须仔细编写代码。特定的COM对象不会被删除,它们是引用计数的,并且您正在对其进行引用。但是当用户将其从文档中删除时,只剩下内存中的一个对象,当然它不再是文档的一部分。
尝试取消引用该对象的成员确实很可能会失败。 Office程序本身可能已删除该对象保留的任何内部引用。你得到一个非常糟糕的例外,这也不常见,0x80004005是E_FAIL,“未指定的错误”。这很难被称为错误,它只是教师对错误报告质量的评分。
理想情况下,您会收到一个告诉您放弃对象引用的事件。很难得到,Office应用程序并不那么健谈。最好的办法是不根本保留一个参考,但只要你需要它就找回来。如果那不实用那么你就试试/ catch-em-all作为最终的后备黑客。
答案 1 :(得分:1)
这是一种可靠且无故障安全的方法吗?
是的,确实如此。没有更好的方法来处理COM对象。在courfse中,您需要在代码中使用COM对象进行delaing时处理异常。此外,我建议处理可以告诉你发生了什么的事件 - 特定对象是否被删除等等。
COM对象是否真的与RCW对象保持一致,或Office可以将其从内存中删除?
Office可以从内存中删除对象。我建议保留对象ID而不是保持直接引用。
在这种情况下,使用悬挂参考不是很危险吗?有更好的方法吗?
没有更好的方法。有关更多信息,请参阅我之前的答案.. >
答案 2 :(得分:1)
您可以像这样使用try-catch组合:
try
{
ProcessString(s);
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
}