Как понять, что поток завершился?
От: Daimond Россия  
Дата: 16.06.04 09:32
Оценка:
TUpdateThread потомок TThread.

Создаю поток, который в фоновом режиме должен выполнить определенные действия, а потом сам уничтожится.


TUpdateThread *Modem;
       ...
    Modem = new TUpdateThread(true);
    Modem->FreeOnTerminate = true;
    Modem->Resume();


Как понять выполняется ли этот поток в данный момент или уже завершился и удалился? Проверка на NULL ни к чему не приводит. При завершившемся потоке, свойвства потока не доступны.
Re: Как понять, что поток завершился?
От: akasoft Россия  
Дата: 16.06.04 09:45
Оценка:
Здравствуйте, Daimond, Вы писали:

D>Как понять выполняется ли этот поток в данный момент или уже завершился и удалился?


Событие OnTerminate() потока.

Occurs after the thread's Execute method has returned and before the thread is destroyed.

... << RSDN@Home 1.1.4 beta 2 >>
Re[2]: Как понять, что поток завершился?
От: Daimond Россия  
Дата: 16.06.04 10:13
Оценка:
Здравствуйте, akasoft, Вы писали:

A>Здравствуйте, Daimond, Вы писали:


D>>Как понять выполняется ли этот поток в данный момент или уже завершился и удалился?


A>Событие OnTerminate() потока.


A>

A>Occurs after the thread's Execute method has returned and before the thread is destroyed.


Поднимать там флаг... можно... А есть какие-нибудь другие способы?
Re[3]: Как понять, что поток завершился?
От: TObject Россия  
Дата: 16.06.04 10:24
Оценка:
Здравствуйте, 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;
... << Rsdn@Home 1.1.4 beta 1 >>
Re[3]: Как понять, что поток завершился?
От: sadomovalex Россия http://sadomovalex.blogspot.com
Дата: 16.06.04 10:26
Оценка:
Здравствуйте, 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>Поднимать там флаг... можно... А есть какие-нибудь другие способы?


Попробуй:
if (WaitForSingleObject(Modem->Handle, 0) == WAIT_OBJECT_0)
{
// поток завершился
}
else
{
}
"Что не завершено, не сделано вовсе" Гаусс
Re[4]: Как понять, что поток завершился?
От: Ihor Osovyak Украина  
Дата: 16.06.04 11:42
Оценка:
Здравствуйте, 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 (не территориального, по ходу выполнения естественно)
Re[5]: Как понять, что поток завершился?
От: Daimond Россия  
Дата: 16.06.04 12:22
Оценка:
Здравствуйте, Ihor Osovyak, Вы писали:


>> А есть какие-нибудь другие способы?


IO>Способов много. Два уже предложили. При использовании техники с WaitForSingleObject проследите с тем, чтобы не было установлено FreeOnTerminate, да не забудьте потом вызвать Free.

IO>Я иногда использую технику посылки сообщения через PostMessage соотв. форме. PostMessage обычно ставлю в конце Execute (не территориального, по ходу выполнения естественно)

Ситуация, в кратце, такая: Пользователь по кнопке запускает поток, который выполняет определенное действие и самоуничтожается. Соответственно, если пользователь нажмет на кнопку, а поток от предыдущего нажатия еще не завершился, ему об этом должны сообщить.
Re[6]: Как понять, что поток завершился?
От: AlexVinS Россия  
Дата: 16.06.04 12:35
Оценка: 1 (1)
Здравствуйте, Daimond, Вы писали:


D>Ситуация, в кратце, такая: Пользователь по кнопке запускает поток, который выполняет определенное действие и самоуничтожается. Соответственно, если пользователь нажмет на кнопку, а поток от предыдущего нажатия еще не завершился, ему об этом должны сообщить.


Лучше так:


Вобщем, не надо давать пользователю возможности делать то, что не надо.


Умный человек знает не многое, но нужное
Re[7]: Как понять, что поток завершился?
От: Daimond Россия  
Дата: 16.06.04 12:49
Оценка:
Здравствуйте, AlexVinS, Вы писали:

AVS>Здравствуйте, Daimond, Вы писали:



D>>Ситуация, в кратце, такая: Пользователь по кнопке запускает поток, который выполняет определенное действие и самоуничтожается. Соответственно, если пользователь нажмет на кнопку, а поток от предыдущего нажатия еще не завершился, ему об этом должны сообщить.


AVS>Лучше так:


AVS>

AVS>Вобщем, не надо давать пользователю возможности делать то, что не надо.


Идея ясная, но мне не подходит... Надо по указателю на поток определить его состояние (полностью завершился и умер или еще живет).
Re[8]: Как понять, что поток завершился?
От: AlexVinS Россия  
Дата: 16.06.04 12:56
Оценка:
Здравствуйте, Daimond, Вы писали:

AVS>>Лучше так:


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;


Умный человек знает не многое, но нужное
Re[3]: Как понять, что поток завершился?
От: ArtDenis Россия  
Дата: 16.06.04 13:04
Оценка:
Здравствуйте, Daimond, Вы писали:


D>>>Как понять выполняется ли этот поток в данный момент или уже завершился и удалился?

A>>Событие OnTerminate() потока.
D>Поднимать там флаг... можно... А есть какие-нибудь другие способы?

Только этот. Других способов нет.
... << Rsdn@Home 1.1.4 beta 1 >>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[4]: Как понять, что поток завершился?
От: ArtDenis Россия  
Дата: 16.06.04 13:05
Оценка: +1
Здравствуйте, TObject, Вы писали:

TO>перекрыть onterminate (надеюсь правильно выразился).

TO>...


Не правильно. Правильно не "перекрыть onterminate", а "назначить обработчик для события onterminate".
... << Rsdn@Home 1.1.4 beta 1 >>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[9]: Как понять, что поток завершился?
От: Daimond Россия  
Дата: 16.06.04 13:14
Оценка:
Здравствуйте, 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>


Так у меня FeeOnTerminate = true, так что когда он умрет, обращение к Modem->Handle должно сгенерировать исключение. Или я ошибаюсь?
Re[10]: Как понять, что поток завершился?
От: AlexVinS Россия  
Дата: 16.06.04 13:20
Оценка:
Здравствуйте, 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 должно сгенерировать исключение. Или я ошибаюсь?

Да, а если и не будет то будет еще хуже

А зачем тебе FreeOnTerminate?


Умный человек знает не многое, но нужное
Re[11]: Как понять, что поток завершился?
От: sadomovalex Россия http://sadomovalex.blogspot.com
Дата: 16.06.04 13:36
Оценка:
D>>Так у меня FeeOnTerminate = true, так что когда он умрет, обращение к Modem->Handle должно сгенерировать исключение. Или я ошибаюсь?
AVS>Да, а если и не будет то будет еще хуже

AVS>А зачем тебе FreeOnTerminate?


Если все это нужно, чтобы пользователь мог запустить только один экземпляр потока одновременно, почему не сделать как предлагалось: поставить Button1->Enable = false в начале Execute потока, а в конце OnTerminate вставить Button1->Enable = true
"Что не завершено, не сделано вовсе" Гаусс
Re[11]: Как понять, что поток завершился?
От: Daimond Россия  
Дата: 16.06.04 13:37
Оценка:
Здравствуйте, AlexVinS, Вы писали:

AVS>Здравствуйте, Daimond, Вы писали:


D>>Здравствуйте, AlexVinS, Вы писали:



D>>Так у меня FeeOnTerminate = true, так что когда он умрет, обращение к Modem->Handle должно сгенерировать исключение. Или я ошибаюсь?

AVS>Да, а если и не будет то будет еще хуже

AVS>А зачем тебе FreeOnTerminate?


Что бы не ждать пока он отработает, чтобы освободить за ним память. Идея такая: запустил и забыл; Запустил еще раз — если уже выполняемся, то отбой.. если нет — создаем поток с помощью new и отрабатываем его.
Re[12]: Как понять, что поток завершился?
От: AlexVinS Россия  
Дата: 16.06.04 13:45
Оценка:
Здравствуйте, Daimond, Вы писали:


AVS>>А зачем тебе FreeOnTerminate?


D>Что бы не ждать пока он отработает, чтобы освободить за ним память. Идея такая: запустил и забыл; Запустил еще раз — если уже выполняемся, то отбой.. если нет — создаем поток с помощью new и отрабатываем его.



В моем варианте это можно сделать в том-же обработчике OnUpdate. Если завершился, FreeAndNil
Дрйгой вариант: DuplicateHandle. И ждать дубля а сам объект потока пусть сам уничтожается, правда новый handle ручками закрыть придется, запустил и забыл не получится.


Умный человек знает не многое, но нужное
Re[8]: Как понять, что поток завершился?
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.06.04 04:16
Оценка: 6 (1) +1
Здравствуйте, 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 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Как понять, что поток завершился?
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 17.06.04 09:24
Оценка:
Hello Daimond, you wrote:

> Как понять выполняется ли этот поток в данный момент или уже завершился

> и удалился? Проверка на NULL ни к чему не приводит. При завершившемся
> потоке, свойвства потока не доступны.

Чем не устраивает WaitForSingleObject?

--
Всего хорошего, Слава
http://slava.users.otts.ru
Posted via RSDN NNTP Server 1.9 beta
Re[9]: Как понять, что поток завершился?
От: Daimond Россия  
Дата: 17.06.04 11:17
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Daimond, Вы писали:


AVS>>>Вобщем, не надо давать пользователю возможности делать то, что не надо.


D>>Идея ясная, но мне не подходит... Надо по указателю на поток определить его состояние (полностью завершился и умер или еще живет).

S>В таком случае все просто как грабли:
S>

S>procedure TForm1.OnMyThreadTerminate(Sender: TObject);
S>begin
S>  FMyThread:= nil;
S>end;

S>end.
S>

S>Идея ясна?

Ясна, буду пробовать.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.