スレッドを終わらせる(not止める)

解決


take  2010-02-09 22:50:46  No: 37503

7Pro+XP
ボタンクリックで生成されるスレッドを同じボタンをクリックした時点で
終了させ、新たなスレッドを立ち上げたい。

過去ログを遡ると
https://www.petitmonte.com/bbs/answers?question_id=2980
「スレッドが終了したことを知るには?」と言うのがありましたがやや
コンセプトが異なるようで参考にならず。

言葉足らずで恐縮ですが目的が理解できた方、解決策をよろしく。

ボタンクリックでMyThreadが立ち上がっているかを判定し、なければcreate、
既にあればスレッドを止めて破棄しcreate、で良いと思うのですが、
その実装がわかりません。


Mr.XRAY  2010-02-09 23:48:55  No: 37504

こんにちは.Mr.XRAYです.
こういうのは参考になりませんか?
一応スレッドの基本的使用方法のサンプルととなっています.

>「スレッドが終了したことを知るには?」と言うのがありましたがやや

基本的には同じです.

http://mrxray.on.coocan.jp/Delphi/plSamples/004_TimerTest.htm#02

使用しているメソッド等は以下を参考にしてください.

TThread のプロパティ
http://docwiki.embarcadero.com/VCL/ja/Classes.TThread_Properties

TThread のメソッド
http://docwiki.embarcadero.com/VCL/ja/Classes.TThread_Methods

あるいは,私のサイトのトップページに参考書のリストがあります.
この中から選んで購入して勉強してください.

>新たなスレッドを立ち上げたい。

どういう意味ですか?

新たなスレッドを立ち上げたい <---> 新たなEXEを立ち上げたい ?
新たな(別の) ?
スレッドの定義(クラス)がいくつかあって,それを順番に実行したい?


Mr.XRAY  2010-02-09 23:56:06  No: 37505

> レッドの定義(クラス)がいくつかあって,それを順番に実行したい?

提示したページのサンプルは,単に,
「スレッドの起動と終了(強制終了または中断)方法」のサンプルです.あしからず.
ということで,質問の意味するとこと違っていたらゴメンナサイ.


Mr.XRAY  2010-02-10 00:00:53  No: 37506

>https://www.petitmonte.com/bbs/answers?question_id=2980
>「スレッドが終了したことを知るには?」と言うのがありましたがやや

にあるように,

    MeThread1.Terminate;

の方がいいかも知れません.


Mr.XRAY  2010-02-10 00:05:14  No: 37507

大変失礼しました.

>https://www.petitmonte.com/bbs/answers?question_id=2980
>「スレッドが終了したことを知るには?」と言うのがありましたがやや

よく読まないでレスしてしまいました.
つまり,ここにズバリのコードあったわけですね(冷汗).


tor  2010-02-10 02:15:28  No: 37508

スレッドが終了したかどうかではなく、起動したかどうかを判定したいのだと解釈しますが
それなら、自分が起動したスレッドを覚えておけばいいだけではないでしょうか?

(初期化)
MyThread := nil;

(ボタン処理)
MyThread.Free; // 前回起動したスレッドを終了させて...
MyThread := TMyThread.Create(false); // 新しいスレッドを起動

MyThread.Freeは、MyThreadがnilなら何もしません。
また、TThreadのデストラクタは必要に応じてTerminateを呼び出すので
「既にあればスレッドを止めて破棄」という動きになると思いますが如何。
(二重にFreeするのを避けるため、スレッドのFreeOnTerminateはfalseにしておいた方が良いでしょう)


KHE00221  2010-02-10 08:39:06  No: 37509

こんなこと?

unit Unit4;

interface

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

type

  TThreadEx = class(TThread)
  private
    FIndex: Integer;
  public
    procedure Execute;override;
    property Index: Integer read FIndex write FIndex;
  end;

  TForm4 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
  public
    procedure OnTerminated(Sender: TObject);
  end;

var
  Form4: TForm4;
  Thread : TThreadEx;
  Index : Integer;

implementation

{$R *.dfm}

procedure TThreadEx.Execute;
begin
    while Terminated = False do
    begin
      Sleep(1);
    end;
end;

procedure TForm4.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    //スレッドの終了を待つ
    if Assigned(Thread) = True then
    begin
      Thread.Terminate;
      while Assigned(Thread) = True do
      begin
        Application.ProcessMessages;
      end;
    end;
end;

procedure TForm4.FormCreate(Sender: TObject);
begin
    Index := 0;
end;

procedure TForm4.OnTerminated(Sender: TObject);
begin
    Memo1.Lines.Add('Thread Terminated : ' + IntToStr(TThreadEx(Sender).Index));
    Thread := nil;
end;

procedure TForm4.Button1Click(Sender: TObject);
begin
    //スレッドの終了を待つ
    if Assigned(Thread) = True then
    begin
      Thread.Terminate;
      while Assigned(Thread) = True do
      begin
        Application.ProcessMessages;
      end;
    end;

    if Assigned(Thread) = False then
    begin
      Thread := TThreadEx.Create(False);
      Thread.OnTerminate := OnTerminated;
      Thread.FreeOnTerminate := True;
      Thread.Index := Index;
      Thread.Resume;
      Memo1.Lines.Add ('Thread Resume : ' + IntToStr(Index));
      Inc(Index);
    end;
end;

end.


take  2010-02-10 23:17:48  No: 37510

レスありがとうございます。そしてスイマセン。

delphiが立ち上がらなくなってしまい現在問い合わせ中です。

「ライセンス情報は見つかりましたが、Delphiには有効ではありません。
  登録しないとDelphi評価版を起動することが出来ません。
  "終了"ボタンを押すとDelphiを終了します。」

と記されたウインドウに終了ボタンのみで手詰まり。
D7Reg.exeを起動しシリアルキーを入れても
「正しい製品情報を見つけることができません。」
で一蹴。

そんなわけでしてこの問題が解決するまで保留になりますがご了承下さい。


take  2010-02-12 23:24:30  No: 37511

改めまして、
KHE00221さんの提示してくれたもので理想通りの動作を得ました。
whileをこう使えばスレッド終了まで待てるんだと感心しきり。

皆さんありがとうございます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加