2012-09-05 40 views
7

Cuando mi código intenta crear una nueva instancia de Microsoft.Office.Interop.PowerPoint.Application, a veces se produce la siguiente excepción:¿Cómo evito las excepciones RPC_E_CALL_REJECTED al realizar la automatización de PowerPoint?

System.Runtime.InteropServices.COMException (0x80010001): Retrieving the COM class factory for component with CLSID {91493441-5A91-11CF-8700-00AA0060263B} failed due to the following error: 80010001 Call was rejected by callee. (Exception from HRESULT: 0x80010001 (RPC_E_CALL_REJECTED)). 
    at System.Runtime.Remoting.RemotingServices.AllocateUninitializedObject(RuntimeType objectType) 
    at System.Runtime.Remoting.Activation.ActivationServices.CreateInstance(RuntimeType serverType) 
    at System.Runtime.Remoting.Activation.ActivationServices.IsCurrentContextOK(RuntimeType serverType, Object[] props, Boolean bNewObj) 
    at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) 
    at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) 
    at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) 
    at System.Activator.CreateInstance(Type type, Boolean nonPublic) 

veces digo porque no sucede constantemente, incluso dada la misma entrada. Además, también ocurre (con la misma falta de consistencia) en otras partes de mi código donde también interactúo con la API de automatización de PowerPoint.

He intentado con la solución this de MSDN, que parece ser la solución más recomendada. Sin embargo, no parece tener ningún impacto ya que todavía observo el mismo comportamiento.

Mis preguntas son:

  1. ¿Funciona solución de MSDN para la automatización de PowerPoint?
  2. ¿Cómo puedo verificar si lo he aplicado correctamente a mi código?
  3. ¿Alguien tiene una solución alternativa?

estoy usando C#, .NET 4 y PowerPoint 2007.

+0

Me encuentro con el mismo problema. Tal vez agregar un Thread.Sleep (100) aquí y allá debería ayudar? Llenar un gráfico requiere cierto tiempo para actualizar grapics, etc. por lo que es posible que deba esperar antes de agregar más datos. – CodingBarfield

Respuesta

2

Me he encontrado con esto antes y Paul B es correcto. Depende de si llama al Powerpoint OM desde el hilo principal (es decir, This_AddIn) o no. Si es así, ppt no debería arrojar estas excepciones. Sin embargo, si llama a ppt desde otro subproceso, debe implementar IMessageFilter para manejar estos errores de bomba de mensaje de Windows de manera eficiente ya que ppt prioriza las llamadas de subproceso principal al OM sobre llamadas desde otros subprocesos, de ahí los rechazos de llamadas.

Hay otra advertencia que requiere más código de placa de caldera para manejar COMException s adicionales como 0x800AC472 (VBA_E_IGNORE). Hay un ejemplo here.

Por lo tanto, la solución completa es a la vez para poner en práctica IMessageFilter y usar algo como sepp2k's código en el que envolver sus llamadas OM con el fin de manejar otros tipos de COMException que puedan ser lanzados.

Por lo tanto, para el código de embalaje como su:

private void TryUntilSuccess(Action action) 
{ 
    bool success = false; 
    while (!success) 
    { 
     try 
     { 
      action(); 
      success = true; 
     } 

     catch (System.Runtime.InteropServices.COMException e) 
     { 
      if ((e.ErrorCode & 0xFFFF) == 0xC472) 
      { // Excel is busy 
       Thread.Sleep(500); // Wait, and... 
       success = false; // ...try again 
      } 
      else 
      { // Re-throw! 
       throw e; 
      } 
     } 
    } 
} 

que se podría llamar con lamdas como este:

TryUntilSuccess(() => 
{ 
    RegisterFilter(); // register this thread for IMessageFilter use 
    ppt_app.DoSomething();   
    UnRegisterFilter(); // unregister this thread for IMessageFilter use 
};) 

La razón de este doble enfoque es que la estrategia IMessageFilter es más eficiente que lanzar excepciones y será más veces que no podrá manejar los mensajes ocupados procedentes de la aplicación. Sin embargo, en otras ocasiones, tendrá que controlar las excepciones por lo que tiene que hacer ambas cosas ...

ver aquí para el IMessageFilter implementation que incluye envolturas

HTH!

Cuestiones relacionadas