Использование устаревшего компонента COM в многопоточной среде C #
-
06-07-2019 - |
Вопрос
У меня есть устаревший COM-компонент, и моя миссия состоит в том, чтобы написать веб-сервис, который обернет COM и разрешит одновременные неблокирующие вызовы.
Прежде всего, поскольку сам COM-объект не имеет состояния, я решил использовать атрибут [ThreadStatic], чтобы у каждого потока был свой экземпляр COM-объекта, чтобы предотвратить использование оператора lock {} и включить реальную параллельную обработку. , но кажется, что все вызовы по-прежнему выполняются синхронно.
Я написал тестовый код, который запускает метод из компонента COM, синхронно с циклом for {}, а затем добавил второй поток, который делает то же самое, но для другого экземпляра объекта COM, и я не увидел никаких изменений, X вызывает всегда использовать Y раз, независимо от количества потоков. Как будто есть статическая блокировка или что-то в этом роде ...
Несмотря на это, отдельные процессы могут обрабатывать каждый вызов одновременно по-настоящему. Что мешает отдельным потокам вести себя одинаково?
Что я могу сделать, чтобы разрешить реальные одновременные вызовы COM-компонента?
Решение
COM поддерживает потоки и учитывает модель потоков, запрошенную коклассом. Он публикует свои требования к потокам со значением ThreadingModel в реестре. Если установлено значение «Квартира» (или отсутствует), COM удостоверится, что все вызовы метода сделаны из однопоточной квартиры, возвращая прокси для интерфейсов, которые вы QI. Прокси-сервер обеспечивает маршалинг вызова в правильный поток.
Вы можете обмануть и использовать указатель интерфейса, который вы получили, когда создали кокласс в потоке STA, и выполнять вызовы без маршалинга. Учитывая, что Coclass уже сказал, что он не способен на многопоточность, это вряд ли будет работать правильно. Вы просто случайным образом испортите внутреннее состояние.