Не могли бы вы объяснить STA и MTA?

Вы вызываете метод non-const из метода const.

378
задан Peter Mortensen 12 September 2012 в 18:22
поделиться

7 ответов

Модель потоков COM называется моделью «квартиры», где контекст выполнения инициализированных объектов COM связан либо с одним потоком (однопотоковая квартира), либо со многими потоками (многопотоковая квартира). В этой модели COM-объект, однажды инициализированный в квартире, является частью этой квартиры на время ее работы.

Модель STA используется для объектов COM, которые не являются потокобезопасными. Это означает, что они не обрабатывают собственную синхронизацию. Обычное использование этого - компонент пользовательского интерфейса. Таким образом, если другой поток должен взаимодействовать с объектом (например, нажав кнопку в форме), то сообщение направляется в поток STA. Примером тому служит система прокачки сообщений в Windows.

Если COM-объект может обрабатывать свою собственную синхронизацию, тогда можно использовать модель MTA, где нескольким потокам разрешено взаимодействовать с объектом без маршализованных вызовов.

347
ответ дан Ry- 12 September 2012 в 18:22
поделиться

Все зависит от того, как обрабатываются вызовы объектов, и насколько им нужна защита. COM-объекты могут попросить среду выполнения защитить их от одновременного вызова несколькими потоками; те, которые не могут быть вызваны одновременно из разных потоков, поэтому они должны защищать свои собственные данные.

Кроме того, во время выполнения также необходимо, чтобы вызов объекта COM не блокировал пользовательский интерфейс, если вызов сделан из потока пользовательского интерфейса.

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

Нити могут быть либо в однопоточной квартире (в этом случае они являются единственной нитью в этой квартире), либо в многопоточной квартире. Они указывают, когда поток инициализирует COM для этого потока.

STA в первую очередь для совместимости с пользовательским интерфейсом, который привязан к конкретному потоку. STA получает уведомления о вызовах для обработки, получая сообщение окна в скрытое окно; когда он делает исходящий вызов, он запускает модальный цикл сообщений, чтобы предотвратить обработку других оконных сообщений. Вы можете указать фильтр сообщений, который будет вызываться, чтобы ваше приложение могло отвечать на другие сообщения.

В отличие от этого все потоки MTA совместно используют один MTA для процесса. COM может запустить новый рабочий поток для обработки входящего вызова, если нет доступных потоков, вплоть до ограничения пула. Потоки исходящих звонков просто блокируются.

Для простоты мы рассмотрим только объекты, реализованные в DLL, которые объявляют в реестре о том, что они поддерживают, установив значение ThreadingModel для ключа своего класса. Существует четыре варианта:

  • Основной поток (значение ThreadingModel отсутствует). Объект создается в основном потоке пользовательского интерфейса хоста, и все вызовы направляются в этот поток. Фабрика классов будет вызываться только в этом потоке.
  • Apartment. Это указывает на то, что класс может работать в любом потоке с однопоточным режимом. Если поток, который создает его, является потоком STA, объект будет выполняться в этом потоке, в противном случае он будет создан в основной STA - если основной STA не существует, для него будет создан поток STA. (Это означает, что потоки MTA, которые создают объекты Apartment, будут маршалировать все вызовы в другой поток.) ​​Фабрика классов может вызываться одновременно несколькими потоками STA, поэтому она должна защитить свои внутренние данные от этого.
  • Free. Это указывает на класс, предназначенный для запуска в MTA. Он всегда будет загружаться в MTA, даже если он создан потоком STA, что снова означает, что вызовы потока STA будут распределены. Это потому, что объект Free обычно пишется с ожиданием того, что он может заблокировать.
  • Both. Эти классы являются гибкими и загружаются в любую квартиру, из которой они созданы. Однако они должны быть написаны так, чтобы соответствовать обоим наборам требований: они должны защищать свое внутреннее состояние от одновременных вызовов, если они загружены в MTA, но не должны блокироваться, если они загружены в STA.

Из .NET Framework просто используйте [STAThread] в любом потоке, который создает пользовательский интерфейс. Рабочие потоки должны использовать адаптер MTA, если только они не собираются использовать COM-компоненты, помеченные Apartment, и в этом случае использовать STA, чтобы избежать проблем с распределением ресурсов и масштабируемостью, если один и тот же компонент вызывается из нескольких потоков (поскольку каждый поток будет иметь ждать компонента по очереди). Все намного проще, если вы используете отдельный COM-объект для потока, независимо от того, находится ли компонент в STA или MTA.

198
ответ дан Mike Dimmick 12 September 2012 в 18:22
поделиться

Я нахожу существующие объяснения слишком глупыми. Вот мое объяснение на простом английском языке:

STA: Если поток создает COM-объект, для которого установлено STA (при вызове CoCreateXXX вы можете передать флаг, который устанавливает COM-объект в режим STA), тогда только этот поток может Получив доступ к этому COM-объекту (это то, что означает STA - Single Threaded Apartment), другой поток, пытающийся вызвать методы этого COM-объекта, скрытно превращается в доставку сообщений потоку, который создает (владеет) COM-объект. Это очень похоже на тот факт, что только поток, создавший элемент управления пользовательского интерфейса, может получить к нему прямой доступ. И этот механизм предназначен для предотвращения сложных операций блокировки / разблокировки.

MTA: если поток создает COM-объект, для которого установлено MTA, то почти каждый поток может напрямую вызывать методы для него.

Это в значительной степени суть этого. Хотя технически есть некоторые детали, которые я не упомянул, например, в параграфе «STA», потоком-создателем должен быть сам STA. Но это почти все, что вам нужно знать, чтобы понять STA / MTA / NA.

73
ответ дан Weipeng L 12 September 2012 в 18:22
поделиться

STA (Single Threaded Apartment) - это концепция, согласно которой только один поток будет взаимодействовать с вашим кодом одновременно. Звонки в вашу квартиру маршалируются через окна сообщений (используя невидимые) окна. Это позволяет звонкам ставиться в очередь и ждать завершения операций.

MTA (Multi-Threaded Apartment) - это место, где все потоки могут работать одновременно, и ответственность за безопасность потоков лежит на вас, как на разработчике.

Намного еще предстоит узнать о многопоточных моделях в COM, но если у вас возникли проблемы с пониманием того, что они из себя представляют, я бы сказал, что понимание того, что такое STA и как оно работает, было бы наилучшим началом, поскольку большинство объектов COM СТА.

Нити квартиры, если нить проживает в той же квартире, что и объект, который она использует, то это нить квартиры. Я думаю, что это всего лишь концепция COM, потому что это всего лишь способ говорить об объектах и ​​потоках, с которыми они взаимодействуют ...

22
ответ дан Brian ONeil 12 September 2012 в 18:22
поделиться

Каждый EXE, в котором размещены элементы управления COM или OLE, определяет состояние своей квартиры. Состояние квартиры по умолчанию STA (и для большинства программ должно быть STA).

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

MTA - Вы можете манипулировать объектом COM в любом потоке вашей программы.

18
ответ дан Nick 12 September 2012 в 18:22
поделиться

Насколько я понимаю, «квартира» используется для защиты COM-объектов от многопоточности.

Если COM-объект не является потокобезопасным, он должен объявить его как STA-объект. Тогда только тот, кто его создает, может получить к нему доступ. Поток создания должен объявить себя как поток STA. Под капотом поток хранит информацию STA в своем TLS (Thread Local Storage). Мы называем это поведение тем, что поток входит в квартиру STA. Когда другие потоки хотят получить доступ к этому COM-объекту, он должен упорядочить доступ к потоку создания. По сути, поток создания использует механизм сообщений для обработки входящих вызовов.

Если COM-объект является потокобезопасным, он должен объявить его как MTA-объект. Доступ к MTA-объекту возможен из нескольких потоков.

11
ответ дан Kevin C. 12 September 2012 в 18:22
поделиться

Код, который вызывает dll COM-объекта (например, для чтения файлов проприетарных данных), может нормально работать в пользовательском интерфейсе, но таинственно зависать от службы. Причина в том, что в пользовательских интерфейсах .Net 2.0 предполагается STA (поточно-ориентированная), в то время как службы предполагают MTA ((до этого службы предполагали STA). Необходимость создания потока STA для каждого COM-вызова в службе может привести к значительным издержкам.

4
ответ дан user2696845 12 September 2012 в 18:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: