2010-03-30 13 views
7

Używam programu COM Interop. Mam połączenie w VB6, które zwraca ciąg około 13000 znaków. Jeśli wykonam wywołanie w czystej VB6, wykonanie zajmuje około 800ms. Jeśli wykonam go za pomocą C# i COM Interop, zajmuje to około 8 sekund. Zakładam, że opóźnienie spowodowane jest marshalingiem.Najszybszy sposób uzyskania dostępu do łańcucha znaków VB6 w języku C#

Jeśli mam rację co do marszałkowania, byłbym wdzięczny, gdyby ktoś mógł zaproponować najszybszy sposób, w jaki mogę to zrobić w języku C#. na przykład Czy byłoby lepiej a) odsłonić go jako tablicę bajtową b) dostarczyć parametr łańcucha byref do warstwy VB6

Byłbym wdzięczny również za przykładowy kod. Próbowałem bezskutecznie. Nie mogłem bezskutecznie próbować.

-

Po komentarzu Franci. Po prostu odwołuję się do dll VB6 (tak w procesie) z C# dll. Oto wyciąg z 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 
    ] 

powinienem chyba podkreślić, że parametr (p_oEventHistory) to kolejny obiekt COM, który mam instancji w C#, ale to trwa około 80ms

S

+0

Pomocne może być podanie pewnych szczegółów na temat kodu VB6 i C#. Czy komponent VB6 jest serwerem out-of-proc lub inproc? Jaki jest faktyczny fragment TLB dla obiektu i właściwości, do której uzyskujesz dostęp. Czy połączenie przebiega przez IDispatch lub zwykły interfejs COM? Czy używasz standardowego koordynatora OLE lub niestandardowego proxy/pośrednika, czy nawet niestandardowego koordynatora? –

+0

Więc udało mi się ogolić 1 sekundę czasu, nie wstrzykując obiektu COM do wywołania COM (poprzez parametr), ale robiąc to wszystko po stronie COM rzeczy. ALE 7 sekund wciąż wydaje się przesadne w przypadku przeniesienia 13000 znaków! –

+1

Coś jeszcze się dzieje. Marshaling BSTR zajmuje mikrosekundy, a nie sekundy. Powinieneś zdebugować kod VB6, ustawić C# exe jako program startowy. –

Odpowiedz

2

Kilka rzeczy: -

  1. Moja VB6 jest trochę zardzewiały, ale twój IDL fragment sugeruje, że metoda GetString faktycznie zwraca obiekt, który implementuje interfejs IXML. Jestem trochę zaskoczony, że Marshal.PtrToStringAuto może zrobić z tym coś użytecznego. Czy mógłbyś zmienić VB6 tak, aby faktycznie zwracał coś typu String?

  2. Efekt COM + jest potencjalnie ogromny. Najpierw proponuję porównać czasy pierwszego wywołania z kolejnymi wywołaniami. COM + będzie musiał uruchomić proces hosta dla komponentu VB6 przy pierwszym wywołaniu, więc pierwsze wywołanie jest zawsze bardziej bolesne. Zauważ, że dzieje się to przy pierwszym wywołaniu, a nie przy tworzeniu instancji obiektu. Po drugie, sposób, w jaki twój komponent jest skonfigurowany w COM +, może również zrobić dużą różnicę; jeśli wyłączysz wszystkie usługi COM +, których faktycznie nie potrzebujesz (na przykład transakcje), możesz usunąć część logiki przechwytywania, którą COM + umieszcza wokół wszystkich wywołań metod. Ostatecznie, jeśli nie potrzebujesz usług oferowanych przez COM +, nie używaj go.

Powiązane problemy