STA (Отдельная резьбовая квартира) COM-объект – рабочие streamи работника?

Неплохо ли создавать рабочие streamи в вашем объекте STA COM (т. Е. COM-объект создает stream для выполнения задачи)? Я думаю, ответ – это зависит!

Например, в моем случае: рабочие streamи, которые я использую, не будут мешать / доступ к COM или COM-сервисам.

Причина, почему я спрашиваю об этом, заключается в том, что по определению STA COM STA может быть только один stream. Истечение нескольких видов streamов идет вразрез с этим принципом, если рабочие streamи и работа они НЕ мешают / не имеют дело с услугами COM / COM. В этом случае я думаю, что это прекрасно, и, на мой взгляд, рабочие streamи не должны рассматриваться COM как часть логической STA.

Что вы думаете об этом?

Нет, это не плохо. Квартиры явно существуют, чтобы помочь вам работать с многопоточным кодом. Поток STA – это безопасный дом для COM-сервера, который не является streamобезопасным, модель поточной сборки квартиры COM гарантирует, что он всегда используется поточно-безопасным способом. Все, что вам нужно сделать, это маршал указателя интерфейса, который вы хотите использовать в рабочем streamе (например, IGlobalInterfaceTable), и вы можете вызывать методы, не делая ничего особенного.

Разумеется, это не бесплатно, есть накладные расходы, связанные с маршалингом вызова. Насколько зависит от того, насколько отзывчив stream STA, когда он накидывает свой цикл сообщений. Если вы намеревались создать рабочий stream явно для использования этого COM-сервера многопоточным способом, то, конечно, вы не будете впереди, вы сделали это медленнее.

Не позволяйте рабочим streamам использовать COM в любом случае, и все должно быть в порядке. Это означает, что вы не можете вызывать COM-объекты у рабочего и вы не можете вызывать API-интерфейсы времени выполнения от рабочего … прямо или косвенно.

Важно понять, что любые новые streamи, которые вы создаете, – это новые streamи сами по себе; это вообще не имеет значения, какой stream создал их. Две важные вещи: (1), что эти новые streamи сами называют CoInitializeEx и либо каждый из них получает свою STA, либо совместно используют MTA, и (2) любые указатели COM-объектов, которые вы передаете между streamами, получают маршалирование соответствующим образом. Никогда не пропускайте указатель COM-объекта из одного streamа в другой в глобальной переменной; вместо этого используйте GIT или CoMarshalInterThreadInterfaceInStream .

(Единственное исключение: вы можете передавать COM-указатели свободно между streamами MTA, но только после того, как этот указатель был надлежащим образом привязан к MTA в первую очередь.)

Кроме того, вам нужно очень хорошо знать, какие объекты живут и каковы их близость. Если вы создаете объект в streamе STA и маршали указатель на другой stream, то типичным случаем является то, что объект будет по-прежнему жить в этом исходном streamе STA с вызовами, возвращающимися к этому streamу, если только вы не предпримете определенные шаги для указания иначе. (Здесь нужно посмотреть: какая модель streamовой передачи объекта, и является ли она «агрегатом беспорядочного маршаллера»).

Так что это не плохо. но будьте уверены, что вы это сделаете соответствующим образом. Например, вы можете подумать, что использование двух streamов может быть более эффективным; но потом понимаем, что много времени тратится на этот рабочий stream, обращаясь к объекту исходного streamа, что дает худшую производительность, чем однопоточный случай. Поэтому сначала вы должны тщательно продумывать свои темы и страtagsю объектов.

(Сказав все это, вы можете, конечно, развернуть столько streamов, сколько хотите, которые не вызывают CoInitialize, если они не используют COM-объекты или COM-объекты каким-либо образом, если эти streamи нуждаются в так или иначе с streamами, которые используют COM, вам решать эту связь с помощью любого «classического» механизма IPC по вашему выбору – например, сообщений, глобалов и т. д.),