Środowisko wykonawcze COM zajmuje się wysyłaniem wywołań metod do obiektu COM w STA: masz rację, że jest to oparte na tym samym mechanizmie systemu operacyjnego, który jest używany do wysyłania komunikatów systemu Windows, ale nie musisz się martwić aby tak się stało - COM robi to za ciebie pod maską.
Musisz się martwić o to, do której STA będą używane Twoje obiekty COM. Jeśli tworzysz obiekty COM z powiązanymi mieszkaniami przy użyciu COM Interop z usługi WCF, musisz zachować ostrożność.
Jeśli wątek, w którym to zrobisz, nie jest wątkiem STA, wówczas wszystkie przetwarzane obiekty COM będą domyślnie przechowywane w domyślnym Host STA dla procesu roboczego IIS. Nie chcesz, aby tak się stało: wszystkie obiekty COM dla wszystkich operacji serwisowych znajdą się w tej samej STA. Wskazówka znajduje się w nazwie - istnieje tylko jeden wątek dla wszystkich obiektów - wszystkie wywołania do ich metod będą serializowane, czekając na jedyny wątek w mieszkaniu, aby je wykonać. Twoja usługa nie będzie skalowalna, aby obsłużyć wielu współbieżnych klientów.
Należy upewnić się, że obiekty COM, które są tworzone w celu obsługi określonego żądania WCF, znajdują się w osobnej STA, niezależnie od obiektów tworzonych dla innych żądań. Istnieją zasadniczo dwa sposoby, aby to zrobić:
- rozpędzają własny wątek z wyszczególnieniem
ApartmentState.STA
w SetApartmentState()
zanim się rozpocznie, na których instancji obiektów COM dla konkretnego wniosku. Jest to podejście opisane przez Scotta Seely'a w the link in Kev's answer: zapewnia on, że każde wywołanie operacji serwisowej jest wywoływane na nowym wątku zainicjowanym przez STA. Mocniejszym, ale bardziej skalowalnym rozwiązaniem w tym zakresie byłoby wdrożenie puli wielokrotnego użytku wątków zainicjowanych STA.
- Hostuj swoje obiekty COM w aplikacji COM +, aby żyły w oddzielnym procesie DllHost, gdzie COM + (poprzez jego abstrakcję o nazwie the
Activity
) może zająć się umieszczaniem obiektów dla różnych żądań w różnych stacjach STA.
Nie jestem do końca pewien, co masz na myśli, gdy mówisz o oddzwonieniach. Być może masz na myśli wywołania metody COM na interfejsie COM zaimplementowanym w zarządzanym kodzie, poprzez referencję przekazaną do obiektów COM jako argument do jednej z metod obiektów COM: jeśli tak, to powinno po prostu działać. Ale może masz na myśli coś innego, w takim przypadku być może mógłbyś zmienić pytanie, by wyjaśnić.
'localThreadFinished' nie jest nigdzie zdefiniowane, o ile mogę powiedzieć ... był twój zamiar zadeklarować go na szczycie' ThreadProc', jak 'AutoResetEvent localThreadFinished = (AutoResetEvent) O'? – transistor1