L'incapacité d'IMessageFilter à gérer 0x800AC472 (VBA_E_IGNORE) rend la mise en œuvre IMessageFilter sans importance?

De msdn, il semble que IMessageFilter ne traite pas toutes les exceptions, par exemple, à certains endroits, les applications bureautiques "suspendent" leur model d'object, auquel cas il ne peut pas être invoqué et lance: 0x800AC472 (VBA_E_IGNORE)

Pour contourner cela, vous devez mettre votre appel en boucle et attendre qu'il réussisse:

 while(true) { try { office_app.DoSomething(); break; } catch(COMException ce) { LOG(ce.Message); } } { while(true) { try { office_app.DoSomething(); break; } catch(COMException ce) { LOG(ce.Message); } } { while(true) { try { office_app.DoSomething(); break; } catch(COMException ce) { LOG(ce.Message); } } } while(true) { try { office_app.DoSomething(); break; } catch(COMException ce) { LOG(ce.Message); } } { while(true) { try { office_app.DoSomething(); break; } catch(COMException ce) { LOG(ce.Message); } } } while(true) { try { office_app.DoSomething(); break; } catch(COMException ce) { LOG(ce.Message); } } 

Ma question est la suivante: si ce code de chaudière-plaque est nécessaire pour chaque appel au model d'object de l'application bureautique, est-ce qu'il y a lieu de mettre en œuvre IMessageFilter ?

Oui, les deux mécanismes sont indépendants. IMessageFilter est un mécanisme COM général pour gérer les servers COM qui sont devenus catatoniques et ne prendra pas un appel pendant 60 secondes. L'erreur VBE_E_IGNORE est très spécifique à Excel et se produit lorsqu'elle se trouve dans un état où le browser de propriétés est temporairement désactivé. Pensez-y comme un état modal, intentionnellement activé lorsque Excel doit effectuer une opération critique qui doit être complétée avant de pouvoir traiter à nouveau les appels hors process. Un verrou si vous voulez. Il n'est pas associé au time, comme IMessageFilter, mais uniquement par état d'exécution. Geoff Darst de l'équipe VSTO donne quelques informations de base dans ce thread de forums MSDN .

Avoir à écrire ce genre de loops de réessayer est horrible bien sur. Étant donné qu'il s'agit d'un problème d'état d'exécution et en supposant que vous effectuez une interopération avec Excel sans que l'user opère également le programme, il devrait y avoir un moyen de contourner le problème. Si vous supprimez Excel à partir d'un thread de travail dans votre programme, envisagez d'examiner l'interaction entre les threads de votre code pour vous assurer que vous ne créez pas un cas où les threads émettent des appels Excel à peu près au même moment.