Как понять выполняется ли этот поток в данный момент или уже завершился и удалился? Проверка на NULL ни к чему не приводит. При завершившемся потоке, свойвства потока не доступны.
Здравствуйте, akasoft, Вы писали:
A>Здравствуйте, Daimond, Вы писали:
D>>Как понять выполняется ли этот поток в данный момент или уже завершился и удалился?
A>Событие OnTerminate() потока.
A>
A>Occurs after the thread's Execute method has returned and before the thread is destroyed.
Поднимать там флаг... можно... А есть какие-нибудь другие способы?
Здравствуйте, Daimond, Вы писали:
D>Здравствуйте, akasoft, Вы писали:
A>>Здравствуйте, Daimond, Вы писали:
D>>>Как понять выполняется ли этот поток в данный момент или уже завершился и удалился?
A>>Событие OnTerminate() потока.
D>Поднимать там флаг... можно... А есть какие-нибудь другие способы?
перекрыть onterminate (надеюсь правильно выразился).
К примеру так
............
with TMyTheard.Create(true) do
begin
OnTerminate:=TheardDone;
Resume;
end;
...........
procedure TForm1.TheardDone(Sender: TObject);
begin
ShowMessage('Поток отработал');
end;
Здравствуйте, Daimond, Вы писали:
D>Здравствуйте, akasoft, Вы писали:
A>>Здравствуйте, Daimond, Вы писали:
D>>>Как понять выполняется ли этот поток в данный момент или уже завершился и удалился?
A>>Событие OnTerminate() потока.
A>>
A>>Occurs after the thread's Execute method has returned and before the thread is destroyed.
D>Поднимать там флаг... можно... А есть какие-нибудь другие способы?
Здравствуйте, sadomovalex, Вы писали:
S>Здравствуйте, Daimond, Вы писали:
D>>Здравствуйте, akasoft, Вы писали:
A>>>Здравствуйте, Daimond, Вы писали:
D>>>>Как понять выполняется ли этот поток в данный момент или уже завершился и удалился?
A>>>Событие OnTerminate() потока.
A>>>
A>>>Occurs after the thread's Execute method has returned and before the thread is destroyed.
D>>Поднимать там флаг... можно... А есть какие-нибудь другие способы?
S>Попробуй: S>if (WaitForSingleObject(Modem->Handle, 0) == WAIT_OBJECT_0) S>{ S>// поток завершился S>} S>else S>{ S>}
дык человек вероятнее всего работает с установленым FreeOnTerminate, судя по диалогу выше
> А есть какие-нибудь другие способы?
Способов много. Два уже предложили. При использовании техники с WaitForSingleObject проследите с тем, чтобы не было установлено FreeOnTerminate, да не забудьте потом вызвать Free.
Я иногда использую технику посылки сообщения через PostMessage соотв. форме. PostMessage обычно ставлю в конце Execute (не территориального, по ходу выполнения естественно)
>> А есть какие-нибудь другие способы?
IO>Способов много. Два уже предложили. При использовании техники с WaitForSingleObject проследите с тем, чтобы не было установлено FreeOnTerminate, да не забудьте потом вызвать Free. IO>Я иногда использую технику посылки сообщения через PostMessage соотв. форме. PostMessage обычно ставлю в конце Execute (не территориального, по ходу выполнения естественно)
Ситуация, в кратце, такая: Пользователь по кнопке запускает поток, который выполняет определенное действие и самоуничтожается. Соответственно, если пользователь нажмет на кнопку, а поток от предыдущего нажатия еще не завершился, ему об этом должны сообщить.
D>Ситуация, в кратце, такая: Пользователь по кнопке запускает поток, который выполняет определенное действие и самоуничтожается. Соответственно, если пользователь нажмет на кнопку, а поток от предыдущего нажатия еще не завершился, ему об этом должны сообщить.
Лучше так:
1 пользователь нажал кнопку
2 Action, связанный с кнопкой блокируем (Enabled:=false), запускаем поток
3 Когда поток завершился, разблокируем (напр в OnTerminate)
Вобщем, не надо давать пользователю возможности делать то, что не надо.
Здравствуйте, AlexVinS, Вы писали:
AVS>Здравствуйте, Daimond, Вы писали:
D>>Ситуация, в кратце, такая: Пользователь по кнопке запускает поток, который выполняет определенное действие и самоуничтожается. Соответственно, если пользователь нажмет на кнопку, а поток от предыдущего нажатия еще не завершился, ему об этом должны сообщить.
AVS>Лучше так:
AVS>
AVS>1 пользователь нажал кнопку AVS>2 Action, связанный с кнопкой блокируем (Enabled:=false), запускаем поток AVS>3 Когда поток завершился, разблокируем (напр в OnTerminate) AVS>
AVS>Вобщем, не надо давать пользователю возможности делать то, что не надо.
Идея ясная, но мне не подходит... Надо по указателю на поток определить его состояние (полностью завершился и умер или еще живет).
Здравствуйте, Daimond, Вы писали:
AVS>>Лучше так:
AVS>>
AVS>>1 пользователь нажал кнопку AVS>>2 Action, связанный с кнопкой блокируем (Enabled:=false), запускаем поток AVS>>3 Когда поток завершился, разблокируем (напр в OnTerminate) AVS>>
AVS>>Вобщем, не надо давать пользователю возможности делать то, что не надо.
D>Идея ясная, но мне не подходит... Надо по указателю на поток определить его состояние (полностью завершился и умер или еще живет).
тогда что-то типа этого:
procedure TForm1.Action1Update(Sender: TObject);
begin
with Sender as TAction do
begin
Enabled:=WaitForSingleObject(Modem.Handle, 0) <> WAIT_OBJECT_0;
end
end;
D>>>Как понять выполняется ли этот поток в данный момент или уже завершился и удалился? A>>Событие OnTerminate() потока. D>Поднимать там флаг... можно... А есть какие-нибудь другие способы?
AVS>procedure TForm1.Action1Update(Sender: TObject);
AVS>begin
AVS> with Sender as TAction do
AVS> begin
AVS> Enabled:=WaitForSingleObject(Modem.Handle, 0) <> WAIT_OBJECT_0;
AVS> end
AVS>end;
AVS>
Так у меня FeeOnTerminate = true, так что когда он умрет, обращение к Modem->Handle должно сгенерировать исключение. Или я ошибаюсь?
Здравствуйте, Daimond, Вы писали:
D>Здравствуйте, AlexVinS, Вы писали:
AVS>>тогда что-то типа этого:
AVS>>
AVS>>procedure TForm1.Action1Update(Sender: TObject);
AVS>>begin
AVS>> with Sender as TAction do
AVS>> begin
AVS>> Enabled:=WaitForSingleObject(Modem.Handle, 0) <> WAIT_OBJECT_0;
AVS>> end
AVS>>end;
AVS>>
D>Так у меня FeeOnTerminate = true, так что когда он умрет, обращение к Modem->Handle должно сгенерировать исключение. Или я ошибаюсь?
Да, а если и не будет то будет еще хуже
D>>Так у меня FeeOnTerminate = true, так что когда он умрет, обращение к Modem->Handle должно сгенерировать исключение. Или я ошибаюсь? AVS>Да, а если и не будет то будет еще хуже
AVS>А зачем тебе FreeOnTerminate?
Если все это нужно, чтобы пользователь мог запустить только один экземпляр потока одновременно, почему не сделать как предлагалось: поставить Button1->Enable = false в начале Execute потока, а в конце OnTerminate вставить Button1->Enable = true
Здравствуйте, AlexVinS, Вы писали:
AVS>Здравствуйте, Daimond, Вы писали:
D>>Здравствуйте, AlexVinS, Вы писали:
D>>Так у меня FeeOnTerminate = true, так что когда он умрет, обращение к Modem->Handle должно сгенерировать исключение. Или я ошибаюсь? AVS>Да, а если и не будет то будет еще хуже
AVS>А зачем тебе FreeOnTerminate?
Что бы не ждать пока он отработает, чтобы освободить за ним память. Идея такая: запустил и забыл; Запустил еще раз — если уже выполняемся, то отбой.. если нет — создаем поток с помощью new и отрабатываем его.
AVS>>А зачем тебе FreeOnTerminate?
D>Что бы не ждать пока он отработает, чтобы освободить за ним память. Идея такая: запустил и забыл; Запустил еще раз — если уже выполняемся, то отбой.. если нет — создаем поток с помощью new и отрабатываем его.
В моем варианте это можно сделать в том-же обработчике OnUpdate. Если завершился, FreeAndNil
Дрйгой вариант: DuplicateHandle. И ждать дубля а сам объект потока пусть сам уничтожается, правда новый handle ручками закрыть придется, запустил и забыл не получится.
Здравствуйте, Daimond, Вы писали:
AVS>>Вобщем, не надо давать пользователю возможности делать то, что не надо.
D>Идея ясная, но мне не подходит... Надо по указателю на поток определить его состояние (полностью завершился и умер или еще живет).
В таком случае все просто как грабли:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons;
type
TMyThread = class(TThread)
protected
procedure Execute; override;
end;
TForm1 = class(TForm)
BitBtn1: TBitBtn;
procedure BitBtn1Click(Sender: TObject);
private
FMyThread: TMyThread;
procedure InitMyThread;
procedure OnMyThreadTerminate(Sender: TObject);
public{ Public declarations }end;
var
Form1: TForm1;
implementation{$R *.dfm}procedure TMyThread.Execute;
begin
Sleep(15000);
end;
{ TForm1 }procedure TForm1.InitMyThread;
begin
FMyThread := TMyThread.Create(true);
FMyThread.FreeOnTerminate := true;
FMyThread.OnTerminate := OnMyThreadTerminate;
FMyThread.Resume;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if FMyThread = nil
then begin
InitMyThread;
Application.MessageBox('Thread will stop in 15 seconds!', 'MyThread', MB_OK or MB_ICONINFORMATION);
end
else begin
Application.MessageBox('Thread is still alive!', 'MyThread', MB_OK or MB_ICONERROR);
end;
end;
procedure TForm1.OnMyThreadTerminate(Sender: TObject);
begin
FMyThread:= nil;
end;
end.
Идея ясна?
... << RSDN@Home 1.1.4 beta 1 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Hello Daimond, you wrote:
> Как понять выполняется ли этот поток в данный момент или уже завершился > и удалился? Проверка на NULL ни к чему не приводит. При завершившемся > потоке, свойвства потока не доступны.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Daimond, Вы писали:
AVS>>>Вобщем, не надо давать пользователю возможности делать то, что не надо.
D>>Идея ясная, но мне не подходит... Надо по указателю на поток определить его состояние (полностью завершился и умер или еще живет). S>В таком случае все просто как грабли: S>