Принципы объектно-ориентированного программирования

         

Модели потоков в COM



Модели потоков в COM

В начале программирования в СОМ большинство людей мало знает (или не знают вообще) о моделях потоков и окружений в СОМ. Не набравшись опыта, они не понимают, что за модель свободных потоков приходится расплачиваться значительным снижением производительности, когда клиентский поток в однопоточном окружении (single-threaded apartment, STA) используется для создания объекта в многопоточном окружении (multithreaded apartment, MTA). Кроме того, начинающие программисты в СОМ часто не знают о безопасности потоков и о том, чем им угрожает одновременное обращение нескольких потоков к их компонентам СОМ.

Прежде чем вызвать объект СОМ, поток должен объявить свою принадлежность к определенному окружению, указывая, что он может входить в STA или МТА. Клиентские потоки STA


вызывают Colnitiali-ze(NULL) или Со Initialize Ex(О, COINIT_APARTMENTTHREADED), чтобы войти в STA, а потоки МТА вызывают Со Initialize Ех(О, COINIT_MULTI-THREADED) для входа в МТА. Сходным образом в мире .NET у вас есть выбор: вы можете позволить вызывающему потоку в управляемом пространстве объявить свою принадлежность к некоторому окружению. Вызывающий поток в управляемом приложении выбирает МТА как свое место обитания по умолчанию. Это аналогично тому, как если бы вызывающий поток инициализировался с параметрами CoInitializeEx(0, COINIT_MULTITHREADED). Но подумайте об издержках и потерях производительности, которые будут иметь место, если вызывающим потоком будет классический СОМ-компонент STA, разработанный для отдельного потока многопоточного процесса. Несовместимые окружения также приведут к издержкам в связи с дополнительными парами "про-кси/заглушка", за что определенно придется расплачиваться производительностью.

В связи с этим вы можете изменить выбор окружения по умолчанию для управляемого потока в приложении .NET с помощью свойства Apart-mentState класса System. Threading. Thread. Свойство ApartmentState принимает одно из значений:

  • МТА — многопоточное окружение;
  • STA — однопоточное окружение;
  • Unknown — эквивалентно поведению МТА по умолчанию.

До осуществления любых вызовов объекта СОМ вам также нужно задать свойство ApartmentState для вызывающего потока. Заметьте: после создания объекта СОМ изменить свойство ApartmentState нельзя. Поэтому имеет смысл установить свойство потока ApartmentState в программе как можно раньше. Вот как это сделать:

// Установить свойство клиентского потока ApartmentState для входа в STA.

Thread.CurrentThread.ApartmentState = ApartmentState.STA;

// Создать объект COM посредством Interop. MySTA obj STA = new MySTAQ; objSTA.MyMethodQ



Содержание раздела