Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.08.07;
Скачать: CL | DM;

Вниз

Правильное ожидание для завершения потока?   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.045 c
3-1119705083
ks
2005-06-25 17:11
2005.08.07
права доступа к таблице Paradox


1-1121847211
Starter
2005-07-20 12:13
2005.08.07
Взаимодействие дочерних форм в MDI-приложении


1-1121769741
td
2005-07-19 14:42
2005.08.07
как определить текущее время?


14-1121405345
rentgen
2005-07-15 09:29
2005.08.07
Глюки форума или глюки у меня


3-1119954270
АМБ
2005-06-28 14:24
2005.08.07
Изменение имени поля