Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
14-1121668373
Antonn
2005-07-18 10:32
2005.08.07
Помогите найти решение задачки


1-1121986829
waterfoll
2005-07-22 03:00
2005.08.07
Текст и таблички, что использовать?


1-1121867870
ki11er
2005-07-20 17:57
2005.08.07
Shared Section


14-1121514195
Экспериментатор
2005-07-16 15:43
2005.08.07
Как написать скриптик на VB, который бы


8-1112171261
mike_o
2005-03-30 12:27
2005.08.07
Конвертер графики





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский