Die COM-Laufzeit kümmert sich um das Absetzen von Aufrufen von Methoden auf einem COM-Objekt innerhalb einer STA: Sie haben recht, dass dies auf dem Betriebssystemmechanismus für die Verteilung von Windows-Nachrichten basiert, aber Sie müssen sich keine Sorgen machen Damit das möglich ist - COM macht das für Sie unter der Haube.
Was Sie do tun müssen, ist besorgt, welche STA Ihre COM-Objekte leben werden. Wenn Sie Apartment-Threaded COM-Objekte mit COM-Interop von einem WCF-Dienst instanziieren, müssen Sie vorsichtig sein.
Wenn der Thread, für den Sie dies tun, kein STA-Thread ist, werden alle prozessinternen COM-Objekte im Standard-Host STA für den IIS-Arbeitsprozess verarbeitet. Sie möchten nicht, dass dies geschieht: Alle Ihre COM-Objekte für alle Servicevorgänge landen in derselben STA. Der Hinweis ist im Namen - es gibt nur einen Thread für alle Objekte - und alle Aufrufe ihrer Methoden werden serialisiert und warten darauf, dass der einzige Thread in der Wohnung sie ausführt. Ihr Dienst wird nicht für die Verarbeitung mehrerer gleichzeitiger Clients skaliert.
Sie müssen sicherstellen, dass COM-Objekte, die Sie instanziieren, um eine bestimmte WCF-Anforderung zu bedienen, in ihrer eigenen STA getrennt von Objekten sind, die für andere Anforderungen erstellt wurden. Es gibt im Großen und Ganzen zwei Möglichkeiten, dies zu tun:
- Spin up Ihre eigenen Thread unter Angabe
ApartmentState.STA
in SetApartmentState()
bevor Sie sie starten, auf dem die COM-Objekte für eine bestimmte Anforderung zu instanziiert. Dies ist der von Scott Seely in the link in Kev's answer beschriebene Ansatz: Er stellt sicher, dass jeder Dienstoperationsaufruf auf einem neuen STA-initialisierten Thread aufgerufen wird. Eine härtere, aber besser skalierbare Lösung in diesem Sinne wäre die Implementierung eines Pools wiederverwendbarer STA-initialisierter Threads.
- Hosten Sie Ihre COM-Objekte in einer COM + -Anwendung, so dass sie in einem separaten DllHost-Prozess leben, in dem COM + (über seine Abstraktion the
Activity
) die Objekte für unterschiedliche Anforderungen in verschiedene STAs versetzen kann.
Ich bin mir nicht sicher, was genau Sie meinen, wenn Sie auf Rückrufe beziehen. Vielleicht meinen Sie COM-Methodenaufrufe auf einer COM-Schnittstelle, die in Ihrem verwalteten Code implementiert ist, über einen Verweis, der als Argument für eine der Methoden des COM-Objekts an die COM-Objekte übergeben wird: Wenn ja, sollte das einfach funktionieren. Aber vielleicht meinst du etwas anderes, in diesem Fall könntest du vielleicht die Frage ändern, um es zu klären.
'localThreadFinished' nicht überall definiert ist, soweit ich sagen kann ... war Ihre Absicht, es an der Spitze der' ThreadProc', als 'Autoreset localThreadFinished = (Autoreset) o' zu erklären? – transistor1