#windows #com
#Windows #com
Вопрос:
Я понимаю причину STA, но на самом деле не вижу причины для MTA.
COM-объект может быть загружен без каких-либо квартир, верно? Это означает, что он уже может принимать вызовы асинхронно, поскольку никто не накладывает никаких ограничений.
Где я не прав?
Комментарии:
1. STA — это историческая функция COM (с большим количеством кода из Windows для ее поддержки, а иногда и с большими трудностями для разработчика при ее использовании), которая предоставляет многопоточность бесплатно без большой работы со стороны разработчика. MTA — это своего рода противоположность, то есть это не функция.
2. MTA = быстрее. Ничто не сериализуется, если вы не сделаете это вручную. STA = бесплатная функция, если вы не хотите возиться с синхронизацией.
3. MTA по своей сути не быстрее STA. У вас нет сериализации, если вы используете STA в том же потоке, который создал квартиру.
4. Думайте о MTA как о том, что в основном ничего не делает, вот почему я сказал, что это не функция. Реальный вопрос скорее «какова цель STA»? Потоковая модель COM-квартиры (single, apartment, both) была создана более 20 лет назад, поэтому изначально настольные однопоточные приложения (такие как приложения VB) поддерживали многопоточность (включая серверные приложения) без слишком большого количества странных ошибок.
5. Вещь, у которой нет функций, все еще нуждается в названии, чтобы вы могли поговорить об этом.
Ответ №1:
Во-первых, ваше предположение неверно: COM-объект не может быть создан вне какой-либо квартиры. Обычно поток должен создавать COM-объекты только в том случае, если он ранее вызывал CoInitialize или CoInitializeEx , которые помещают его в квартиру. В противном случае создание обычно завершается неудачей. Существует крайний случай неявного многопоточного модуля (если его инициализировал другой поток того же процесса), но даже тогда вы были бы в MTA, просто ненадежным и трудным для отладки способом. Ни один COM-объект никогда не существует, не находясь в квартире.
Причина, по которой вы хотите MTA, заключается в том, что это не обязательно единственная квартира. Процесс может иметь один MTA и произвольно много STA. Вызовы между MTA и любым из STA все еще нуждаются в маршалировании; если бы это было не так, один из потоков MTA мог бы небезопасным образом вызвать поток STA.
На самом деле наличие хотя бы одного STA является скорее правилом, чем исключением: пользовательский интерфейс хочет жить в STA, потому что это зависит от сообщений (например, из-за щелчков мыши и т.д.), Которые должны обрабатываться последовательно.