Форум: "Основная";
Текущий архив: 2005.08.07;
Скачать: [xml.tar.bz2];
ВнизПравильное ожидание для завершения потока? Найти похожие ветки
← →
Erik1 © (2005-07-14 10:38) [0]Както я почитал сатью о замене стандартного WaitFor на более продвинутую функцию ожидания. И вствил ее в свой класс TCustomThread. Поскольку он у меня используется как для обычных програм так и для сервисов, постарался написать уневерсальный вариант. Но последним я тестировал сервис, для него она работала. А вот для обычной апликации находится в состоянии вечного ожидания. Вопрос как ее исправить, чтобы работала о обеих случиях?
procedure MsgWaitFor(Handle: THandle);
Var
Msg: TMsg;
begin
while MsgWaitForMultipleObjects(1, Handle, False, INFINITE, QS_ALLINPUT) = WAIT_OBJECT_0 + 1 do
begin
PeekMessage(Msg, 0, 0, 0, PM_Remove);
if Msg.message <> WM_QUIT then // GetMessage(Msg, 0, 0, 0)
DispatchMessage(Msg); // TranslateMessage(Msg);
end;
end;
← →
Lamer`s (2005-07-14 10:56) [1]что то мне кажется что когда приходит сообшение от системы "QS_ALLINPUT" то Result будет =WAIT_OBJECT_0 + nCount где nCount = количеству твоих потоков.
Win32 Develo...
WAIT_OBJECT_0 + nCount
Input of the type specified in the
dwWakeMask parameter is available in the thread"s input queue.
← →
Lamer`s (2005-07-14 12:12) [2]попробуй
ServiceThread.ProcessRequests(
перед или вместо PeekMessage(Msg, 0, 0, 0, PM_Remove);
← →
Digitman © (2005-07-14 12:50) [3]procedure MsgWaitFor(Handle: THandle);
Var
Msg: TMsg;
begin
while True do //как вариант для осн.потока GUI-приложения - while not Application.Terminated, или для потока сервиса - while MyService.Status = csRunning
case MsgWaitForMultipleObjects(1, Handle, False, INFINITE, QS_ALLINPUT) of
//объект просигналил
WAIT_OBJECT_0: break;
//есть невыбранные сообщения потоку и/или его окнам
WAIT_OBJECT_0 + 1:
// вариант для основного потока GUI-приложения
Application.ProcessMessages;
// вариант для произвольного потока GUI-приложения
if not GetMessage(Msg, 0, 0, 0) then
break
else
begin
TranslateMessage(Msg);
DispatchMessage(Msg)
end;
//вариант для сервис-приложения
begin
if PeekMessage(Msg, 0, WM_MYMESSAGE, WM_MYMESSAGE, PM_Remove) then ... //обработаем интересующее сообщение WM_MYMESSAGE "вручную"
else
ServiceThread.ProcessRequests(False); //передадим диспетчеризацию/обработку диспетчеру
end;
end;
end;
← →
Erik1 © (2005-07-15 11:11) [4]У меня всегда происходит WAIT_OBJECT_0 при ожидании окончания дополнителього потока в GUI приложении. А после все замирает на MsgWaitForMultipleObjects.
← →
Erik1 © (2005-07-15 11:58) [5]Пиходит какойто message $B001 и все, даже незнаю, что это за message.
← →
Digitman © (2005-07-15 12:11) [6]
> У меня всегда происходит WAIT_OBJECT_0 при ожидании окончания
> дополнителього потока
значит ты дождался этого события
> после все замирает на MsgWaitForMultipleObjects.
а зачем ты MsgWaitForMultipleObjects вновь вызываешь ? ты ведь уже дождался ?
← →
Erik1 © (2005-07-15 12:25) [7]Так непонятно, что это за событие? Я его непосылал. Что онo означает незнаю.
procedure MsgWaitFor(Handle: THandle);
Var
Msg: TMsg;
begin
repeat
case MsgWaitForMultipleObjects(1, Handle, False, INFINITE, QS_ALLINPUT) of
WAIT_OBJECT_0: Break;
WAIT_OBJECT_0 + 1:
begin
PeekMessage(Msg, 0, 0, 0, PM_Remove);
case Msg.message of
WM_QUIT, WM_DESTROY: Break;
else
DispatchMessage(Msg);
end;
end;
end;
until False;
end;
← →
Digitman © (2005-07-15 12:31) [8]
> Я его непосылал. Что онo означает незнаю.
раз не посылал, значит и не тебе заботиться о его обработке - на все такие случае вызывай DispatchMessage(), диспетчер сам разберется
← →
Digitman © (2005-07-15 12:39) [9]кстати, какое право ты имеешь выбрав "чужие" сообщения не передать их на обработку адресату ?
ведь WM_QUIT, WM_DESTROY кому-то были посланы ! и этот "кто-то", возможно, расчитывал сделать какие-то обязательные "дела" по получению этих сообщений ..
этим "кто-то" может быть окно любой из существующих на этот момент форм
← →
Erik1 © (2005-07-15 12:42) [10]А по какому критерию выходить из цикла?
← →
Digitman © (2005-07-15 12:55) [11]как по какому ?
по факту WAIT_OBJECT_0 - это первый и главный критерий, ради чего собссно и был организован цикл !
если же выходить из цикла по любому иному критерию (например, Application.Terminated = True), то доп.трэд, которого ты так и не дождался, конечно же будет принудительно снят с выполнения и уничтожен вместе с процессом в ходе ExitProcess() (если еще будет "жив"), но это отнюдь не всегда корректно - "убитый" доп.трэд мог занять некие глоб.ресурсы
← →
Erik1 © (2005-07-15 13:18) [12]Так в томто и дето, что Wait_Object_0 а немогу получить, получаю Wait_Object_0 +1
repeat
case MsgWaitForMultipleObjects(1, Handle, False, INFINITE, QS_ALLINPUT) of
WAIT_OBJECT_0: Break;
WAIT_OBJECT_0 + 1:
begin
PeekMessage(Msg, 0, 0, 0, PM_Remove);
case Msg.message of
0: Break;
end;
TranslateMessage(Msg);
DispatchMessage(Msg)
end;
end;
until False;
← →
Digitman © (2005-07-15 13:28) [13]
> в томто и дето, что Wait_Object_0 а немогу получить
значит поток не завершается и продолжает все это время работать
иначе ситуацию не объяснить, если Wait_Object_0 +1 ты получаешь, а Wait_Object_0 - никогда
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.08.07;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.042 c