Maneira mais rápida de acessar a string vb6 em c#
-
23-09-2019 - |
Pergunta
Estou usando o COM Interop. Eu tenho uma chamada no VB6 que retorna uma série de aproximadamente 13000 chars. Se eu executar a chamada no VB6 puro, é necessário cerca de 800ms para executar. Se eu o executar via C# e COM Interop, leva cerca de 8 segundos. Estou assumindo que o atraso é causado pelo organização.
Se eu estiver correto sobre o marechaling, ficaria agradecido se alguém pudesse sugerir da maneira mais rápida que eu posso colocar isso no C#. Por exemplo
Eu também apreciaria algum código de exemplo. Eu tentei o
Marshal.PtrToStringAuto(Marshal.ReadIntPtr(myCOMObject.GetString, 0)
para nenhum proveito.
--
Seguindo o comentário de Franci. Estou simplesmente referenciando a DLL VB6 (então em processo) de uma DLL C#. Aqui está um extrato da 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
]
Eu provavelmente deveria ressaltar que o parâmetro (p_oeventhistory) é outro objeto com que estou instantando em C#, mas isso leva cerca de 80ms
S
Solução
Um par de coisas: -
Meu VB6 está um pouco enferrujado, mas seu trecho IDL sugere que o método GetString realmente retorna um objeto que implementa a interface IXML. Estou meio surpreso que o marechal.ptrtoStringauto possa fazer qualquer coisa útil com isso. Você poderia alterar o VB6 para que ele realmente retorne algo da string de tipo?
O efeito do COM+ é potencialmente enorme. Em primeiro lugar, sugiro que você compare os horários para a primeira invocação versus invocações subsequentes. O com+ precisará aumentar um processo de host para o seu componente VB6 na primeira vez em que é invocado, para que a primeira chamada seja sempre mais dolorosa. Observe que isso acontece na primeira invocação, não na instanciação do objeto. Em segundo lugar, a maneira como seu componente está configurado no COM+ também pode fazer uma grande diferença; Se você desativar todos os serviços COM+ que você realmente não precisa (por exemplo, transações), poderá remover parte da lógica de interceptação que o COM+ coloca em todas as invocações do método. Por fim, se você não precisar dos serviços que o Com+ fornece, não o use.
Outras dicas
Eu consideraria usar arquivos mapeados de memória ou tubos nomeados.