-
использую COM объекты в отдельном потоке, к сервисе.
надо ли делать цикл обработки сообщений вида:
var msg: TMsg; .... while GetMessage(msg, 0, 0, 0) do DispatchMessage(msg);
в своём потоке (который с COM работает) ?
-
Если STA - обязательно, хотя и не обязательно использовать именно GetMessage. Подойдет любой способ обнаружения и выборки с последующей диспетчеризацией.
-
Что такое STA ? (погуглил, но толком не понял про sta com objects) раньше у меня было так:
procedure TMyThread.Execute;
begin
inherited;
while not Terminated do
Sleep(1);
end; теперь сделал так: procedure TMyThread.Execute;
var
msg: TMsg;
begin
inherited;
while not Terminated and GetMessage(msg, 0, 0, 0) do
DispatchMessage(msg);
end; и при закрытии поток стал "виснуть", т.е. не прекращаетсяи всё. Как сделать правильно?
-
> надо ли делать цикл обработки сообщений
Если потоку (и/иди его окнам, если он таковые создает) никто не посылает никакие сообщения, то не надо.
-
Автор COM библиотек говорит, что без такого цикла не работают обратные COM вызовы.
Но я толком не пойму, почему поток виснет когда я делаю такой цикл. наверное я его неправильно реализовываю?
-
> почему поток виснет когда я делаю такой цикл
наверно потому, что GetMessage ждет сообщения, а ей никто ничего не шлет
-
> Автор COM библиотек говорит, что без такого цикла не работают > обратные COM вызовы
Если он при этом не подтверждает свою говорильню конкретными аргументами и/или исходниками - фтопку такого автора и все его "творчество".
> ей никто ничего не шлет
А она, наивная, ждет письма до второго пришествия)
-
2 Сергей М
Аргумент прост до безобразия. COM диспетчеризует вызовы в STA поток, используя сообщения, для чего создает в этом потоке при вызове CoInitialize специальное окно.
2 istok
Завершай так: MyThread.Terminate; PostThreadMessage(MyThread.ThreadId, WM_NULL,...) или так PostThreadMessage(MyThread.ThreadId, WM_QUIT,...) В последнем случае проверку Terminated в потоке можно выкинуть .
-
> Автор COM библиотек говорит, что без такого цикла не работают > обратные COM вызовы
Там видать имелся в виду случай, когда клиет использует интерфейс сервера в доп. потоке. На сервере COM-объект, созданный в STA, без такого цикла не получит ни одного вызова методов своих интерфейсов извне его апартамента. А так как при использовании Callback-интерфейса клиент и сервер меняется местами, то это утверждение справедливо, но это не твой случай.
Или ты в вопросе имел в виду именно что сервис является клиентом? Тогда это твой случай. Используешь событийные интерфейсы - необходим цикл выборки. А то я-то сначала понял так, что у тя в сервисе создаются COM-объекты.
-
никаких TERMINATED, нафига??
и делай while GetMessage(msg, 0, 0, 0) do begin TranslateMessage(Msg); а затем уже DispatchMessageW(Msg); end ато ерунда получается.
-
2 MultIfleX
Крут ты, брат! Ох, кру-у-ут!
-
> TranslateMessage(Msg); > а затем уже > DispatchMessageW(Msg);
> ато ерунда получается
Подтверждаю - не всмятку)
-
|