Почему я должен использовать потоковую модель Both COM вместо Free?

Согласно в этой статье, если я регистрирую свой COM-объект с потоковой моделью «Оба» или «Бесплатная», этот объект должен быть полностью потокобезопасным. В частности, все обращения к глобальным общим переменным должны быть синхронизированы, и все обращения к переменным-членам также должны быть синхронизированы. Это требует больших усилий.

Теперь я понимаю, что возможность зарегистрировать мой объект с использованием «свободной» потоковой модели является преимуществом и, возможно, стоит заплатить цену за то, чтобы сделать его полностью потокобезопасным. Но зачем мне делать все то же самое и вместо этого регистрировать свой объект, используя потоковую модель «Оба»? В чем будет преимущество? Как выбрать между «Оба» и «Бесплатно»?


person sharptooth    schedule 01.12.2009    source источник


Ответы (1)


Обе модели потоков

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

Если вы помечаете свой компонент как MTA и ваш компонент создается из STA, то ваш компонент будет создан в отдельной квартире MTA и " результирующий маршалинг между подразделениями может снизить производительность настолько, чтобы свести на нет всю работу, вложенную в создание эффективного компонента со свободными потоками ". Однако, если модель потоковой передачи вашего компонента помечена как «Оба», то она будет создана внутри квартиры объекта STA, и к ней будет осуществляться прямой доступ.

Поэтому, если вы думаете, что ваш компонент может быть вызван из STA (все COM-объекты VB6 являются STA), вы можете пометить потоковую модель как «Оба».

Хорошая статья в базе знаний о моделях потоковой передачи OLE.

Модель с бесплатными потоками

Вы можете захотеть использовать модель потока «Free», если ваш компонент использует другие компоненты, отмеченные как «Free». Если ваш компонент был помечен как «Оба», то могло произойти чрезмерное переключение квартир между компонентом «Оба», работающим в STA и MTA. Как правило, старайтесь создать компонент как можно ближе к вызывающему абоненту (то есть в той же квартире), при этом работая должным образом во всех сценариях.

Другая ситуация, которая требует пометки вашего компонента как «Свободный», - это если он явно блокирует (например, Thread.Sleep). Если компонент помечен как «Оба» и создается в STA, то компонент блокирует перекачку сообщений STA.

Другие соображения и сценарии

Если вы планируете использовать компонент в IIS, следует учесть и другие моменты. Для IIS рекомендуется "Оба". В основном, чтобы избежать проблем с блокировкой многопоточных компонентов Apartment, оперативного доступа к COM + ObjectContext и того факта, что «бесплатные» многопоточные компоненты используют контекст безопасности системы (если вам требуется доступ к контексту безопасности пользователя). См. Выбор модели потоков для компонентов в IIS для получения дополнительной информации о IIS. соображения потоковой передачи.

Также следует учитывать поддержку COM + и поведение ваших компонентов, если они запускаются в COM +, а также то, передаются ли и сохраняются ли указатели на интерфейсы.

Отличная статья - Потоки COM и архитектура приложений в приложениях COM +. Он фокусируется на COM +, но также обсуждает COM. Если у вас возник вопрос, прочтите раздел «Рекомендации по многопоточным моделям». Microsoft удалила исходную статью, поэтому я даю ссылку на копию.

person Randy supports Monica    schedule 01.12.2009
comment
Это отличное объяснение, за исключением того, что теперь я не понимаю, почему я должен отмечать свой объект как «Свободный», а не как «Оба», поскольку, похоже, «Оба» более выгодны. - person sharptooth; 01.12.2009
comment
Потому что вы можете захотеть принудительно использовать его в MTA, то есть к нему будут обращаться многие другие объекты в MTA, и вы не хотите, чтобы они использовали прокси для STA, на котором ваш объект создан (потребителем VB6) - person wqw; 01.12.2009
comment
Что ж, если есть два потока - один STA и один MTA, и оба вызывают CoCreateInstance (), тогда ... Если объект помечен как Оба, одна копия создается в STA и одна в MTA. Вызовы от Thread1 к STA и от Thread2 к MTA являются прямыми, остальные проходят через прокси. Если объект помечен как Free, обе копии находятся в одном MTA, и только вызовы от Thread1 к MTA проходят через прокси, остальные вызовы являются прямыми. Это все круто, но почему объект должен применять последнее, а не позволять этому быть проблемой клиентов? - person sharptooth; 01.12.2009
comment
@sharptooth, если вашему объекту требуется MTA, вы должны сообщить COM, что он должен быть в MTA. В ответе приведен пример: если вы выполняете блокировку, вам нужно быть в MTA. - person user253751; 04.02.2021