STAThread и многопоточность

Из статьи MSDN о STAThread:

Indicates that the COM threading model for an application is single-threaded apartment (STA).

(Для справки, это вся статья.)

Однопоточная квартира ... Ладно, это перешло мне в голову. Кроме того, я где-то читал, что, если ваше приложение не использует COM-взаимодействие, этот атрибут вообще ничего не делает. Итак, что именно он делает и как влияет на многопоточные приложения? Должны ли многопоточные приложения (включая все, от кого-либо, использующего Timer до вызовов асинхронных методов, а не только пулы потоков и т.п.) использовать MTAThread, даже если это «на всякий случай»? Что на самом деле делают STAThread и MTAThread?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
103
0
81 251
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Что это делает, это гарантирует, что CoInitialize будет вызван с указанием COINIT_APARTMENTTHREADED в качестве параметра. Если вы не используете какие-либо компоненты COM или элементы управления ActiveX, это никак на вас не повлияет. Если да, то это критически важно.

Элементы управления, которые являются многопоточными, фактически являются однопоточными, их вызовы могут обрабатываться только в том подразделении, в котором они были созданы.

Еще немного подробностей из MSDN:

Objects created in a single-threaded apartment (STA) receive method calls only from their apartment's thread, so calls are serialized and arrive only at message-queue boundaries (when the Win32 function PeekMessage or SendMessage is called).

Objects created on a COM thread in a multithread apartment (MTA) must be able to receive method calls from other threads at any time. You would typically implement some form of concurrency control in a multithreaded object's code using Win32 synchronization primitives such as critical sections, semaphores, or mutexes to help protect the object's data.

When an object that is configured to run in the neutral threaded apartment (NTA) is called by a thread that is in either an STA or the MTA, that thread transfers to the NTA. If this thread subsequently calls CoInitializeEx, the call fails and returns RPC_E_CHANGED_MODE.

Статья MSDN полезна с точки зрения COM, но можете ли вы сказать мне, когда .NET вызывает CoInitialize() в ответ на атрибут STAThread / ApartmentState? Примечание: статья в MSDN находится здесь: Функция CoInitializeEx.

jrh 04.05.2017 17:48

Использует ли поток-> SetApartment внутренне CoInitialize()? Я проследил атрибут STAThread до самого конца, но след остыл (я не могу найти источник для Thread::SetApartment). Документирован ли где-нибудь класс Thread из thread.h (COM thread.h)? Это MFC, ATL или что-то еще?

jrh 05.05.2017 22:18

@jrh я не знаю более подробной информации, чем это извините

1800 INFORMATION 05.05.2017 22:21
Ответ принят как подходящий

Распределение потоков по квартирам - это концепция COM; если вы не используете COM и ни один из вызываемых вами API-интерфейсов не использует COM «под прикрытием», то вам не нужно беспокоиться о квартирах.

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

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

1800 INFORMATION 03.10.2008 05:44

Вызов объекта STA в потоке STA к объекту MTA будет маршалирован в поток MTA (если объект MTA не реализует маршалер со свободным потоком). Как я уже сказал, детали могут быть сложными. (Я работал в команде COM несколько лет ухмылка)

Bruce 03.10.2008 06:26

Иногда вам нужно знать об этом, даже если вы не используете COM напрямую. Поток должен использовать модель однопоточного апартамента, если он отображает какие-либо графические окна. Вот почему [STAThread] всегда отображается поверх основного метода в приложении Windows Forms.

Justin Ethier 15.05.2009 17:43

Разве что-то вроде диалогового окна «Шрифт или файл» не может использовать COM без вашего ведома? Я бы предположил, что они работают внутри, разве это не означает, что почти любое приложение Windows Forms потребует установки STAThread? Простите мое наивное предположение, поскольку я на самом деле не занимался программированием COM.

Brett Ryan 05.02.2010 20:05

Более подробный ответ для интересующихся: stackoverflow.com/questions/4154429/apartmentstate-for-dummi‌ es

jgauffin 12.01.2011 14:53

Но вы должны помнить и работать в STA, когда вы программируете пользовательский интерфейс в winforms. Даже если вы не используете COM.

Alex Blokha 13.03.2012 22:33

Извините за восстановление старой цепочки комментариев, но @BrettRyan поднимает здесь очень важный вопрос. Я действительно нашел эту ветку, потому что, если вы используете диалог выбора файла в winforms, не отмечая Main () как STAThread, он умрет. Я также могу (слава Богу) подтвердить, что это не повлияло ни на одного из нескольких фоновых воркеров, которые у меня есть в моей программе, предположительно потому, что они, насколько мне известно, не делают никаких вызовов COM.

Josh Bibb 14.11.2012 19:26

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

quixver 19.12.2014 00:51

STAThread написан перед основной функцией проекта графического интерфейса C#. Он ничего не делает, но позволяет программе создать единственный поток.

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