Понимание потоковых моделей в COM при программировании на Delphi
Страница 6. Сервер STA


 

Правило #5:

Для того, чтобы сервер STA работал бы правильно, его поток должен включать в себя цикл, непрерывно проверяющий наличие оконных сообщений (windows messages) и, соответственно, их обрабатывающий. 

Другими словами, следующий фрагмент показывает основы реализации работающего потока STA:

var
rMsg : TMsg;

begin

  CoInitializeEx (NIL, COINIT_APARTMENTTHREADED); >у >

  >{ главный цикл сообщений потока }

   >while (GetMessage (rMsg, 0, 0, 0)) do

      DispatchMessage (rMsg);

   CoUninitialize;

end; 

Если Вы планируете создать поток STA, не имеющий цикла обработки оконных сообщений, Вы должны учитывать, что если Вы пытаетесь получить доступ к объекту, созданному в этом STA, из других потоков (очевидно, в других STA), Ваши вызовы не будут успешно выполнены и Ваш вызывающий поток "зависнет". Очевидно, что причина происходящего кроется в том, что мы только что узнали. Я бы хотел подчеркнуть также, что цикл сообщений необходим только с той точки зрения, что Ваш поток STA собирается обслуживать объекты для потоков в других подразделениях. Действительная цель цикла обработки оконных сообщений заключается в том, что COM может выстраивать последовательно все вызовы, приходящие от всех потоков. Другими словами, если Вы собираетесь создать поток STA, который работает с объектами COM внутри того же самого потока, то нет абсолютно никакой нужды в цикле сообщений.

Например, если клиентское приложение создает поток STA и внутри этого потока создает объект COM, работает с ним и затем завершает, то нет никакого смысла в цикле сообщений вообще, т.е. 

procedure TMySTAThread.Execute;var

  >pObject1 : IObject1;

begin

  CoInitializeEx (NIL, COINIT_APARTMENTTHREADED);

   // Создает объект object1, делает с ним что-то (something) и завершается

  pObject1 := CreateOleObject ('Server.Object1') as IObject1; >

  pObject1.DoSomething; >

  >pObject >1. >DoSomeOtherThing >;

  >pObject >1 := >NIL >;

   // Цикл сообщений не нужен, так как мы уже все сделали

  >CoUninitialize >;

end ; 

Очевидно, что если Вы планируете использовать модель STA в Вашем приложении, то по существу говоря это приложение является многопоточным, в котором каждый поток живет в отдельном STA. Это означает, что для COM имеется возможность делать одновременные вызовы Вашего приложения, если оно создает несколько STA (отметьте существенную разницу: для каждого STA вызовы выстраиваются последовательно, но в целом приложение может иметь несколько STA, вызовы к которым могут поступать одновременно). Это приводит нас к другому правилу, весьма важному для STA:

 
« Предыдущая статья   Следующая статья »