Управление COM-потоком квартир (STA, MTA) в процессе приложения C # - PullRequest
0 голосов
/ 29 марта 2019

Я пытаюсь понять C # нить квартиры и у меня есть вопросы:

  1. Что такое квартира и что она содержит?

  2. Квартира и архитектура потоков COM.

    Процесс может иметь ноль или более однопоточных квартир и ноль или одну многопоточнуюквартира.

    Может ли кто-нибудь предоставить пример кода C # или пример приложения, где:

    1. 0 STA, 0 MTA
    2. 1STA, 0 MTA
    3. 2 STA, 0 MTA
    4. 0 STA, 1 MTA
    5. 1 STA, 1 MTA
    6. 2 из STA, 1 из MTA

И когда каждый случай должен \ может использоваться?

1 Ответ

1 голос
/ 29 марта 2019
  1. COM-квартира - это логическая концепция.Квартира содержит темы.Квартира STA может содержать только одну нить (отсюда и название «однопоточная квартира»).MTA может содержать много потоков (отсюда и название «многопоточная квартира»).Поскольку MTA может содержать столько потоков, сколько ему нужно, в процессе может быть не более одного MTA.

  2. Вы можете легко написать эти примеры самостоятельно.Просто создайте потоки в C #, и в начале метода точки входа потока вызовите Thread.SetApartmentState .Любые потоки, выбранные вами как MTA, будут жить в одном MTA;все потоки, для которых вы установили STA, будут жить в своем собственном STA.

Не пытайтесь вмешиваться в состояние квартиры потока потока.Эти потоки являются общими (это пул), поэтому нежелательно пытаться изменить их работу.Кроме того, если поток принадлежит квартире, он не может быть изменен.

О, я почти забыл ответить «когда каждый случай можно / нужно использовать»: никогда, если вы можете помочь.

Даже при написании COM-объектов я всегда предпочитал писать объекты с «свободной резьбой» (неважно, в какой квартире они находятся), но я могу это сделать, потому что у меня есть сверхспособность понимать потоки изная, как использовать мьютекс.Модель потоков была создана потому, что (или, по крайней мере, отчасти потому, что) многие ранние полупрофессиональные разработчики VB не понимали этих концепций (возможно, до сих пор не понимают?), И поэтому люди из COM пытались придумать систему, которая все еще позволялаони легко делают тонкие вещи.

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

Дополнительные вопросы из комментариев:

мы можем установить квартиру для потока, используя Thread.SetApartmentState для потока или атрибут [STA \ MTAThread] для метода.Но можем ли мы получить \ установить квартиру для объектов?

Нет.COM-объект принадлежит квартире, в которой он был создан, конец.

все вызовы объекта, который был создан в квартире STA его потоком, должны выполняться этим потоком.

Для объектов, принадлежащих STA: да и нет.«Нет», потому что из-за особой (раздражающей) магии, о которой я говорил ранее (прокси и заглушки), вы можете получить ссылку на COM-объект, принадлежащий STA # 1, в другом потоке в STA # 2 и сделатьвызов на это оттуда.«Да» потому, что под капотом происходит то, что магия прокси / заглушки отправляет сообщение из одного потока в другой, и метод фактически всегда выполняется в потоке, которому принадлежит объект.Таким образом, вы можете / инициировать / вызов нескольких квартир из любого потока ... но сам метод будет выполняться в потоке, которому принадлежит объект.Проблема, которая часто возникает, заключается в том, что по той или иной причине магия прокси / заглушки не доступна для данного COM-объекта ... в этом случае вы застряли;вы действительно можете использовать этот объект только в потоке, в котором он живет.

Для MTA он немного слабее - специальный (раздражающий) маршалинг вступает в игру только при пересечении apartment границы, а не границы потоков.Поэтому вы должны быть осторожны с обработкой синхронизации самостоятельно, если у вас в MTA несколько потоков.

...