2010-03-30 10 views
7

Estoy usando COM Interop. Tengo una llamada en VB6 que devuelve una cadena de aproximadamente 13000 caracteres. Si ejecuto la llamada en VB6 puro, se requieren aproximadamente 800ms para ejecutar. Si lo ejecuto a través de C# y COM Interop tarda unos 8 segundos. Supongo que la demora es causada por el marshaling.La forma más rápida de acceder a VB6 String en C#

Si estoy en lo correcto acerca de la clasificación, le agradecería a alguien que me sugiera la manera más rápida de conseguir esto en C#. p.ej. ¿Sería mejor que a) exponerlo como una matriz de bytes b) proporcionar un parámetro de cadena byref en la capa VB6

También apreciaría un código de muestra. Probé el

Marshal.PtrToStringAuto(Marshal.ReadIntPtr(myCOMObject.GetString, 0) 

inútilmente.

-

Siguiente a partir del comentario de Franci. Simplemente estoy haciendo referencia al dll de VB6 (en proceso) de un dll de C#. He aquí un extracto de OLEView

interface _MyCOMObect : IDispatch { 
     ... 
     [id(0x60030006)] 
     HRESULT GetString(
         [in] _IEventHistory* p_oEventHistory, 
         [out, retval] _IXML**); 
     ... 
    }; 

    [ 
     uuid(09A06762-5322-4DC1-90DD-321D4EFC9C3E), 
     version(1.0), 
     custom({17093CC6-9BD2-11CF-AA4F-304BF89C0001}, "0") 
    ] 
    coclass MyCOMObject { 
     [default] interface _CFactory; 
    }; 

    [ 
     odl, 
     uuid(C6E7413F-C63A-43E4-8B67-6AEAD132F5E5), 
     version(1.0), 
     hidden, 
     dual, 
     nonextensible, 
     oleautomation 
    ] 

Probablemente debería señalar que el parámetro (p_oEventHistory) es otro objeto COM que estoy crear instancias en C#, pero que dura aproximadamente 80 ms

S

+0

Puede serle útil si proporciona algunos detalles sobre su código VB6 y C#. ¿El componente VB6 es un servidor fuera de proc o en proceso? ¿Cuál es el fragmento real de TLB para el objeto y la propiedad a la que está accediendo? ¿La llamada pasa por IDispatch o una interfaz COM regular? ¿Está utilizando un Marshaller OLE estándar o un proxy/stub personalizado o incluso un Marshaller personalizado? –

+0

Así que he logrado reducir 1 segundo el tiempo al no inyectar un objeto COM en la llamada COM (a través del parámetro) pero hacerlo todo en el lado COM de las cosas. ¡PERO 7 segundos todavía parece excesivo para transferir 13000 caracteres! –

+1

Hay algo más que está pasando. Alinear un BSTR lleva microsegundos, no segundos. Debería depurar el código VB6, configurar el C# exe como el programa de inicio. –

Respuesta

2

Un par de cosas: -

  1. Mi VB6 es un poco oxidado, pero su extracto IDL sugiere el método GetString realidad devuelve un objeto que implementa la interfaz iXML. Estoy sorprendido de que Marshal.PtrToStringAuto pueda hacer algo útil con esto. ¿Podrías cambiar el VB6 para que realmente devuelva algo de tipo String?

  2. El efecto de COM + es potencialmente enorme. En primer lugar, le sugiero que compare los tiempos de la primera invocación versus las invocaciones posteriores. COM + tendrá que activar un proceso de host para su componente VB6 la primera vez que se invoca, por lo que la primera llamada siempre es más dolorosa. Tenga en cuenta que esto sucede en la primera invocación, no en la instanciación de objetos. En segundo lugar, la forma en que su componente está configurado en COM + también puede marcar una gran diferencia; Si deshabilita todos los servicios COM + que realmente no necesita (por ejemplo, transacciones), es posible que pueda eliminar parte de la lógica de interceptación que COM + coloca alrededor de todas las invocaciones de métodos. En definitiva, si no necesita los servicios que proporciona COM +, no los use.

Cuestiones relacionadas