Подтвердить что ты не робот

Каковы ограничения потока STA по сравнению с потоками MTA?

Если мы создадим поток STA следующим образом: Thread.SetApartmentState(STA);, то он не может запустить код, помеченный атрибутом [MTAThread].

Мы видели [STAThread] в Windows и консольных приложениях, но я никогда не видел код с атрибутом [MTAThread] и не знаю, какие библиотеки .NET используют этот атрибут.

Мой вопрос в том, каковы ограничения потока с состоянием квартиры, установленного в STA, в сравнении с потоками с состоянием квартиры MTA (естественные потоки .NET)?

4b9b3361

Ответ 1

то он не может запустить код, помеченный атрибутом [MTAThread].

Это не так, как это работает. Тип квартиры - это свойство потока, а не метода. Вы видите атрибут [STAThread], применяемый только к методу Main() для .NET-программы. Он определяет тип квартиры самого первого потока, который создается для запуска программы. Необходимо, потому что вы не можете вызвать SetApartmentState() после того, как поток запущен. Кроме того, атрибут не имеет значения, поток остается в STA на протяжении всей жизни. Вы никогда не видите [MTAThread], потому что это значение по умолчанию.

Поток, который STA имеет некоторые ограничения. Он никогда не может блокироваться, потому что это блокирует и часто затормозит любой код, который пытается вызвать метод объекта COM с потоковой передачей квартиры. И он должен накачивать цикл сообщений, чтобы COM мог маршировать вызов метода из другого потока. Вызовы метода Marshaled могут выполняться только тогда, когда поток "неактивен", а не занят выполнением какого-либо кода. Цикл сообщения обеспечивает состояние "не занято".

Существуют также требования к COM-компоненту. Он должен поддерживать маршалинг, ограничивая себя подмножеством типов, поддерживаемых Automation, чтобы можно было использовать стандартный маршаллер. Или путем предоставления пары прокси/заглушки для пользовательского маршалинга. Раздел реестра HKCR\Interface\{iid}\ProxyStubClsid32 определяет, как выполняется маршалинг.

Совместно доступ к потолочному объекту квартиры между STA и потоком MTA явно поддерживается. Поток STA должен создать его, любые вызовы в потоке MTA (или другие потоки STA) будут маршалированы. Это гарантирует, что компонент только когда-либо видит вызовы, выполненные в одном потоке, обеспечивая тем самым безопасность потока. Никакой дополнительной блокировки не требуется.

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

Ответ 2

Я не думаю, что это имеет значение, если вы не используете COM. Если вы это сделаете, то в некоторых случаях COM-объекты могут быть доступны только из одного или другого типа потока. Если COM-объект работает в обеих квартирах, попробуйте выполнить тесты производительности. Или читайте о COM-квартирах на MSDN. Но я не думаю, что это важно для производительности, это скорее выбор дизайна или что-то в этом роде.