Среда выполнения COM следит за отправкой вызовов методов для объекта COM внутри STA: вы правы, что это основано на том же механизме ОС, который используется для отправки сообщений Windows, но вам не нужно беспокоиться о созданииэто происходит - COM делает это для вас под капотом.
Что вам делать нужно беспокоиться о том, в какой STA будут жить ваши COM-объекты. Если вы создаете экземпляр COM с поточной квартиройобъекты, использующие COM Interop из службы WCF, нужно соблюдать осторожность.
Если поток, для которого вы это делаете, не является потоком STA, то все внутрипроцессные COM-объекты будут жить по умолчанию Host STA для рабочего процесса IIS.Вы не хотите, чтобы это произошло: все ваши COM-объекты для всех сервисных операций окажутся в одной и той же STA.Подсказка кроется в названии - для всех объектов существует только один поток - и все вызовы их методов будут сериализованы, ожидая, пока один и единственный поток в квартире выполнит их.Ваша служба не будет масштабироваться для обработки нескольких одновременно работающих клиентов.
Необходимо убедиться, что объекты COM, которые вы создаете для обслуживания определенного запроса WCF, находятся в собственной STA, отдельной от объектов, созданных для других запросов.Есть два основных способа сделать это:
- Раскрутить свой собственный поток, указав
ApartmentState.STA
в SetApartmentState()
перед его запуском, для которого создаются экземпляры COM-объектов для определенного запроса.Этот подход подробно описан Скоттом Сили в по ссылке в ответе Кева : он гарантирует, что каждый вызов операции службы вызывается в новом инициализированном STA потоке.Более сложным, но более масштабируемым решением в этом направлении было бы реализовать пул повторно используемых STA-инициализированных потоков. - Размещайте ваши COM-объекты в приложении COM +, чтобы они жили в отдельном процессе DllHost, где COM + (через его абстракцию, называемую
Activity
) может позаботиться о размещении объектовдля разных запросов в разные STA.
Я не совсем уверен, что вы имеете в виду, когда ссылаетесь на обратные вызовы.Возможно, вы имеете в виду вызовы COM-методов для какого-либо COM-интерфейса, реализованного в вашем управляемом коде, посредством ссылки, передаваемой COM-объектам в качестве аргумента одному из методов COM-объектов: если это так, это должно сработать.Но, возможно, вы имеете в виду что-то еще, и в этом случае, возможно, вы могли бы изменить вопрос, чтобы уточнить.