スレッドが終了したかを知るには?

解決


nish  2005-06-30 17:39:12  No: 16104  IP: 192.*.*.*

スレッドが終了したかを知るのに何かありますか?

現在、スレッドに状態フラグを渡して、
スレッドのコントストラクトでTrueにし、
スレッドが終了する時にFalseにしています。
何か簡単に知る術はありますか?

Delphi6 Enterprise使用。

編集 削除
nish  2005-06-30 18:10:52  No: 16105  IP: 192.*.*.*

終了時にwaitを使ってみたのですが
アクセスエラーがでてしまいました。

  if Thread1 <> nil then
  begin
      Thread1.Terminate;
      Thread1.wait;
  end;

編集 削除
nish  2005-06-30 18:18:57  No: 16106  IP: 192.*.*.*

度々すみません。
コード間違えました。
×Thread1.wait;
○Thread1.WaitFor;

スレッドが終了した時にThread1にnilが入るような
処理?イベント?はないんでしょうか?

編集 削除
メラトニン  2005-07-03 17:53:24  No: 16107  IP: 192.*.*.*

OnTerminateイベントでしょう。
以下サンプルです
ちなみにTMyThread内に途中終了処理が無いので途中終了しません。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TMeThread = class(TThread)
  private
    { Private 宣言 }
  protected
    procedure Execute; override;
  end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    MeThread1 :TThread;
    procedure MeThread1Terminate(Sender: TObject);
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses Math;

{$R *.dfm}

{ TMeThread }

procedure TMeThread.Execute;
var i:Integer;
begin
  inherited;
  for i:=0 to 100 do
    Sleep(10);

  beep;
end;

////////////////////////////////////////////////
procedure TForm1.Button1Click(Sender: TObject);
begin
  If MeThread1=nil then
  begin
    caption:='作成しました';
    MeThread1:=TMeThread.Create(True);
    MeThread1.FreeOnTerminate:=True;
    MeThread1.OnTerminate:=MeThread1Terminate;
    MeThread1.Resume;
  end else begin
    caption:='終了要求出しました';
    MeThread1.Terminate;
  end;

end;

procedure TForm1.MeThread1Terminate(Sender: TObject);
begin
  MeThread1:=nil;
  caption:='破棄しました';
end;

end.

編集 削除
nish  2005-07-04 12:26:04  No: 16108  IP: 192.*.*.*

OnTerminateなんてあるんですね!?
見落としてました(^^;

ちなみにマルチスレッドの時は
どう判定してnilを入れればいんでしょうか?

編集 削除
メラトニン  2005-07-04 12:57:40  No: 16109  IP: 192.*.*.*

マルチスレッドじゃなくって複数のTThreadを作成した時ですよね?

MeThread1.OnTerminate:=MeThread1Terminate;
MeThread2.OnTerminate:=MeThread1Terminate;
MeThread3.OnTerminate:=MeThread1Terminate;

としたら
procedure TForm1.MeThread1Terminate(Sender: TObject);
begin
  TMeThread(Sender):=nil;
end;

(Sender: TObject)の中身が送り主のTMeThreadです。

編集 削除
にしの  2005-07-04 13:52:13  No: 16110  IP: 192.*.*.*

> (Sender: TObject)の中身が送り主のTMeThreadです。
Senderは、送り主のTMeThreadオブジェクトですが、入れ物は違うかもしれませんよ。
引数はvarではありませんし。
TListなどで管理して、Terminateしたらリストから消してやるほうがよいかと思います。

編集 削除
nish  2005-07-04 15:38:30  No: 16111  IP: 192.*.*.*

メラトニンさん、にしのさんありがとうございます。
とても勉強になります。

あと初歩的な質問なんですが、、、
> マルチスレッドじゃなくって複数のTThreadを作成した時ですよね?
って、マルチスレッドと複数のTThread作成って
どう違うのすか?
同じものだと思っていましたので。。。

編集 削除
anone  2005-07-04 15:43:35  No: 16112  IP: 192.*.*.*

暗黙のうちに作られるメインスレッドがあるから。TThread の派生クラスのインスタンスを
ひとつ作った時点ですでにマルチスレッドと言える。

編集 削除
nish  2005-07-04 16:08:01  No: 16113  IP: 192.*.*.*

あ〜なるほど!
ありがとうございました。

編集 削除
メラトニン  2005-07-04 18:17:27  No: 16114  IP: 192.*.*.*

にしのさん
>>TMeThread(Sender):=nil;
確かにこれは問題あるかもしれません、
[[解決]]付いたって事はnishさん分かってるのかな?

編集 削除
anone  2005-07-06 13:28:54  No: 16115  IP: 192.*.*.*

> 確かにこれは問題あるかもしれません

絶対問題があるでしょう。特定の変数に nil を代入したいときに
そのインスタンスをキャストして代入してもまったく無意味です。

編集 削除