COM - rausbekommen ob der aktuelle thread im MTA ist



  • Kann man (vor Windows 7) irgendwie einfach und ohne Race-Condition rausbekommen ob der aktuelle Thread im MTA ist?
    Also das für was man unter Windows 7 CoGetApartmentType verwenden würde.



  • Ich spekulier mal: Per CoGetObjectContext() ein IComThreadingInfo Interface holen und dann einfach dessen GetCurrentApartmentType() Methode aufrufen.



  • Ich hab ja kein "current object". (Und ich wüsste auch net wie COM das rausfinden wollen würde.)

    Hintergrund:

    Ich muss aus 'nem beliebigen Thread raus Aufrufe in ein COM Objekt reintun. Also Interfaces marshallen, z.B. über den GIT. Würde ich mir aber gerne für das MTA sparen, da es ja doch etwas Overhead verursacht, und die meisten Aufrufe eben aus dem MTA kommen.

    Falls du dazu nen ganz anderen Vorschlag hast hab ich natürlich auch nix dagegen.



  • Naja, steht eigentlich alles was hier bisher erwähnt wurde auch in der Doku zu CoGetApartmentType, auch das mit den Race Conditions. Ich vermute, wenn es eine andere Möglichkeit geben würde, hätte Microsoft das an der Stelle erwähnt.
    Wobei ich mich fragen muss, ob das nicht mit CoInitializeEx funktionieren würde. Laut MSDN müsste die Funktion RPC_E_CHANGED_MODE zurückgeben, wenn der Thread bereits initialisiert wurde und man ein anderes Concurrency Model setzen will.



  • Ja, das könnte man probieren.
    Wobei ich fürchte dass das auf einem "implicit MTA" Thread relativ teuer könnte. (Also Threads die nicht explizit in einem STA sind und daher "implizit" im MTA.)
    Oder vielleicht auch nicht, müsste ich ausprobieren. Aber so richtig sauber finde ich die Lösung sowieso nicht, daher werd' ich mir den Aufwand vermutlich sparen.

    Was allerdings reichen müsste, wäre das Objekt einfach im MTA zu erstellen. Die GIT Operationen schneinen nämlich laut meiner Messung vergleichsweise sehr flott zu sein wenn man ins "originale" STA zurückmarshalt, also da rein wo die Instanz ursprünglich erstellt wurde.

    Könnte ich auch einfach mal ausprobieren.



  • Hui, das geht gut 🙂

    Objekt im Main Thread (STA) erstellt, über GIT gemarshalt und im MTA verwendet:
    GIT-Marshaling-Kosten: ca. 320 us
    RPC-Call-Kosten*: ca. 27 us/call

    Objekt im MTA erstellt, über GIT gemarshalt und im MTA verwendet:
    GIT-Marshaling-Kosten: ca. 2 us
    RPC-Call-Kosten*: ca. 27 us/call

    In einem unterschiedlichen Apartment ist das über den GIT Marshalen also ca. 10x ** teurer als der RPC-Call.
    Im selben ist es ca. 1/10 ** so teuer -- auch wenn man selbst gar nicht weiss dass es das selbe Apartment ist. Was ich sehr gut finde.

    *: Das COM Objekt lebt in einem anderen Prozess auf der selben Maschine ("out-of-process COM server"). OK, die im anderen Prozess anfallenden Dispatch-Kosten kommen noch dazu, ist aber Standard COM - ATL Zeugs. Die "eigentliche" Funktion die das ganze implementiert tut aber "nix".
    **: Ja, ich weiss dass 10 x 27 nicht 320 ist und dass 10% von 27 auch nicht 2 sind. Mir geht's aber nur um Grössenordnungen.


Anmelden zum Antworten