IMessageFilter无法处理0x800AC472(VBA_E_IGNORE)是否使得实现IMessageFilter变得无关紧要?

7
msdn上看来,IMessageFilter似乎不能处理所有异常,例如,在某些时候,办公应用程序会“挂起”它们的对象模型,此时无法调用并抛出:0x800AC472(VBA_E_IGNORE)
为了解决这个问题,您需要将调用放在循环中,并等待其成功:
while(true)
{
    try
    {
        office_app.DoSomething();
        break;
    }
    catch(COMException ce)
    {
        LOG(ce.Message);
    }
}

我的问题是:如果每次调用办公应用程序的对象模型都需要这个样板代码,那么实现 IMessageFilter 有什么意义吗?
1个回答

8
是的,这两种机制是独立的。IMessageFilter是一种处理COM服务器进入“僵尸”状态并且在60秒内无法处理调用的通用COM机制。VBE_E_IGNORE错误非常特定于Excel,并且在禁用属性浏览器时发生。将其视为一种模态状态,当Excel需要执行必须在处理外部进程调用之前完成的关键操作时,有意地打开它。就像一个锁。与IMessageFilter不同,它与时间无关,而完全由执行状态确定。 VSTO团队的Geoff Darst在此MSDN论坛线程中提供了一些背景信息。

不得不编写这种重试循环当然是可怕的。考虑到这是一个执行状态问题,并假设您正在与Excel进行互操作而用户没有同时操作该程序,则应该有一种方法来避开这个问题。如果您正在从程序的工作线程中抨击Excel,则请考虑审查代码中线程之间的交互,以确保您不会创建一个情况,即线程在大致同时发出Excel调用。


谢谢,汉斯。你的观点确实很有用。我非常注意确保两个线程不会同时向Excel发送请求,但是需要强制进行这些重试的样板代码让我感到有点烦恼。我想如果每个调用都在重试循环中,我可以完全删除消息过滤器,因为所有异常都将被捕获,尽管效率可能会降低。 - Pat Mustard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接