Вопрос

Можете ли вы объяснить STA и MTA своими словами?

Кроме того, что такое потоки квартир и относятся ли они только к COM?Если да, то почему?

Это было полезно?

Решение

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

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

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

Другие советы

Все зависит от того, как обрабатываются вызовы объектов и насколько им необходима защита.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, если только они не собираются использовать ApartmentCOM-компоненты, помеченные -, и в этом случае используйте STA, чтобы избежать проблем с маршаллингом и масштабируемостью, если один и тот же компонент вызывается из нескольких потоков (поскольку каждому потоку придется по очереди ждать компонента).Гораздо проще использовать отдельный COM-объект для каждого потока, независимо от того, находится ли компонент в STA или MTA.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top