![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
как отловить завершение потока? [D7, WinXP]
aser © (2004-01-04 10:36:00)
Я создаю поток с помощью ф-ии
h:=CreateThread(nil,0,@FNC,@par,0,ThreadID);
Как мне отследить его завершение? Я так понимаю что нужно делать ловушку с помощью SetWindowsHookEx. Но только что-то ни как не найду на какое событие она(hook) должна реагировать?
Подскажите, плз, какое событие (WM_...) или как по другому отловить завершение потока?
Ihor Osov'yak (2004-01-04 20:15:00) [1]
что то ты немного... эта... Темнишь. Во!
Поток с помощью апишных вызовов создаешь, а потом от апи хвункциональности VCL
требуешь.. Непоследовательно как то. Если все же апи, то смотри [9]..
Если VCL - то смотри в сторону TThread, в частности на OnTerminate.
Только учти, что зацепка OnTerminate возникает еще перед окончанием потока, но уже после отработки Execute и в контексте потока.. См. модуль
classes.pas, function ThreadProc (реализацию смотри, чтобы понять, когда OnTerminate "fired")
Бином Ньютоныч (2004-01-04 18:12:00) [2]
Есть толко 3 способа:
1)функция ожидания с обработкой очереди сообщений или без
2)Отправка сообщения из потока перед самым завершением + опять же ожидание, если нужна гарантия, что поток точно завершился.
3)Генерация события прямо из потока.
Можно еще использовать очередь асинхронных вызовов, но практически то-же самое, что и отправка сообщения. Других способов нет.
aser (2004-01-04 17:22:00) [3]
Спасибо. Но видимо надо объяснить совсем конкретно. Программа написана не на API, а с использованием VCL. Хотелось бы что бы код выглядел как то так:
...
var
h:THandle=0;
...
procedure TForm1.ButtonAClick(Sender: TObject);
var
ThreadID:Cardinal;
f:DWORD;
begin
h:=CreateThread(nil,0,@tst,nil,0,ThreadID);
end;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
// !!
УСТАНОВКА_ОБРАБОТЧИКА_НА_СОБЫТИЕ_"завершение_потока_h"
// !!
end;
Ihor Osov'yak (2004-01-04 16:47:00) [4]Хм.. А кто тебе мешает в конце FNC запостить (PostMessage) какое-то нотификационное сообщение..
Если же этого делать не хочешь, то все равно придется периодически вызывать
WaitForSingleObject в каком-то цыкле наблюдения, или по таймеру, но уже не с INFINITE, а c 0 (вызов с 0 не приводит к "застреванию" на WaitForSingleObject пока поток не окончен..), и анализировать возращаемое значение, примерно так, как я говорил в ветке http://www.delphimaster.ru/cgi-bin/forum.pl?id=1073201169&n=0
Зы. Есть еще другие способа, но они, имхо, еще более кривые, чем периодическое дергание WaitForSingleObject(h, 0), что также есть немного криво...
Бином Ньютоныч (2004-01-04 16:41:00) [5]
Ты бы лучше сразу написал конкретно, что надо, а не "типа" и "Следующая инструкция", а то так и будем воду толочь. Если нужна обработка сообщений, то примерно так:
h:=CreateThread(nil,0,@tst,nil,0,ThreadID);
repeat
case MsgWaitForMultipleObjects(1, h, false, qs_allevents) of
wait_object_0:
begin
ShowMessage("Цепочка завершилась");
Break;
end;
wait_object_0 + 1: Application.ProcessMessages;
else ErrorHandling;
end;
until Application.Terminated;
aser (2004-01-04 16:30:00) [6]
Удалено модератором
aser (2004-01-04 15:12:00) [7]
У меня получился такой код:
{1} h:=CreateThread(nil,0,@tst,nil,0,ThreadID);
{2} if WaitForSingleObject(h,INFINITE)=0 then ShowMessage("Цепочка завершилась");
{3}Caption:="Следующая инструкция";
...
...
НОя бы хочу что бы ShowMessage("Цепочка завершилась") выполнилась по завершению потока, а стока {3} и последующие выполнялись сразу. Т.е прогамма работает и работает, а по завершению потока возникает типа прерывание.
Бином Ньютоныч (2004-01-04 13:04:00) [8]
Она обеспечивает кое-какой дополнительный сервис - взводит переменную IsMultiThread и обеспечивает корректную работу механизма обработки исключений
aser (2004-01-04 12:50:00) [9]
Да спасибо! Я уже и сам нашел эту ф-ю. А кстати, чем лучше BeginThread чем CreateTread???
Бином Ньютоныч (2004-01-04 11:43:00) [10]
Например WaitForSingleObject(h,...) И лучше используй BeginThread вместо CreateThread.