Понимание потоковых моделей в COM при программировании на Delphi - Сервер 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: