Почему COM + игнорирует модель многопоточности квартиры? - PullRequest
1 голос
/ 14 мая 2009

У меня есть компонент STA COM, который помещается в приложение COM +. Клиент создает несколько экземпляров класса в этом компоненте и вызывает их методы параллельно. Класс зарегистрирован правильно - "ThreadingModel" для соответствующего идентификатора класса - "Квартира".

Я вижу, что несколько вызовов одного и того же метода одного и того же класса выполняются параллельно внутри компонента - в реальном коде компонента. Они выполняются в одном и том же процессе, но в разных потоках.

Что происходит? COM + игнорирует модель потоков? Разве модель STA не должна позволять выполнять только один вызов за раз?

Ответы [ 4 ]

1 голос
/ 19 мая 2009

Чтобы избежать путаницы, я не буду использовать термин «объект» в этом ответе. Вместо этого давайте использовать «класс» и «экземпляр». Я уверен, что мы все понимаем разницу между ними.

Маркировка вашего COM-класса с ThreadingModel «Квартира» означает, что его экземпляры будут загружены в STA. Процесс создания этих экземпляров будет определять, будут ли они все входить в одну STA или в отдельные STA.

Как вы обнаружили, COM + загрузил несколько экземпляров в отдельные STA.

Гарантия, которую вы получаете с STA, заключается в том, что один экземпляр никогда не будет доступен нескольким потокам одновременно. Отдельные экземпляры одного и того же класса, если они загружены в отдельные STA, несомненно, могут быть доступны для разных потоков одновременно.

Таким образом, STA - это действительно способ защиты данных вашего экземпляра. Не ваши данные класса. Любые «общие» или «статические» данные в вашем коде COM должны быть защищены вами.

1 голос
/ 14 мая 2009

STA гарантирует, что ваш объект доступен только из одного конкретного потока - защита от общей переменной не требуется.

Я помню, что для VB6 существовал особый режим (я не помню, как он был назван): вы могли позволить COM + порождать несколько STA, каждый из которых использовал выделенный объект. Переменные этих объектов, тем не менее, рассматривались как локальное хранилище потоков - поэтому, хотя к вашему COM-классу обращаются несколько раз из нескольких потоков, совместного использования переменных не происходит. Возможно ли, что вы используете эту функцию?

1 голос
/ 14 мая 2009

Вы передавали объект объектам, которые живут в другой квартире? Если да, нужно ли было выполнить маршалинг интерфейса до того, как вы это сделали? Вам не удалось собрать маршаллера со свободной резьбой?

Грубо говоря, если вы передаете интерфейс вашего объекта объекту в другой квартире (потоке), то вы должны обязательно упорядочить интерфейс . Если вы этого не сделаете, то можете обнаружить, что ваш объект можно свободно вызывать из объектов в другой квартире, поскольку они не вызывают через прокси-сервер, который правильно обрабатывает вызов.

Все вызовы объекта должны быть сделаны на его нить (в пределах своей квартиры). Это запрещено вызывать объект прямо из другого потока; с помощью объекты в такой манере может вызвать проблемы для приложений. Смысл этого правила заключается в том, что все указатели на объекты должны быть маршалировал, когда проходил между квартиры. COM обеспечивает следующее две функции для этого:

* CoMarshalInterThreadInterfaceInStream marshals an interface into a stream object that is returned to the caller.
* CoGetInterfaceAndReleaseStream unmarshals an interface pointer from a stream object and releases it.

Эти функции переносят вызовы CoMarshalInterface и Функции CoUnmarshalInterface, которые требует использования MSHCTX_INPROC флаг.

1 голос
/ 14 мая 2009

Нет, не совсем. STA буквально означает «однопотоковая квартира», что означает, что в квартире может работать только один поток. Теперь вопрос в том, что такое квартира. Квартира - это логическое пространство внутри процесса, и его реализация может варьироваться от структуры к структуре. Microsoft реализует квартиры как потоки, из-за чего STA (в контексте COM Microsoft) переводится в однопотоковый поток, то есть может быть несколько квартир / потоков, но каждая квартира / поток будет однопоточной в случае STA.

Вы можете обобщить эту вещь на MTA самостоятельно. Из того, что я сказал выше, MTA является многопоточным потоком в контексте COM.

...