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

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

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

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

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

Ответ 1

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

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

Ответ 2

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

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

Дополнительная информация из MSDN:

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

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

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

Ответ 3

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