STAThread и многопоточность - PullRequest
102 голосов
/ 03 октября 2008

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

Указывает, что модель потоков COM для приложения является однопоточным (STA).

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

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

Ответы [ 3 ]

59 голосов
/ 03 октября 2008

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

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

3 голосов
/ 03 октября 2008

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

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

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

Объекты, созданные в однопоточном квартира (STA) принимает вызовы метода только из своей квартиры нить, так звонки сериализуются и поступают только на границах очереди сообщений (когда Win32 функция PeekMessage или SendMessage называется).

Объекты, созданные в потоке COM в многопоточная квартира (MTA) должна быть возможность получать вызовы методов от другие темы в любое время. Ты бы как правило, реализуют некоторую форму управление параллелизмом в многопоточном код объекта с использованием Win32 примитивы синхронизации, такие как критические разделы, семафоры или мьютексы, чтобы помочь защитить объект данные.

Когда объект настроен на беги в квартире с нейтральной резьбой (NTA) вызывается потоком, который находится в либо STA или MTA, этот поток переводы в нта. Если этот поток впоследствии вызывает CoInitializeEx, звонок не удается и возвращается RPC_E_CHANGED_MODE.

0 голосов
/ 21 марта 2012

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

...