実行のあるなしを判定するには?


ハイジ  2006-08-04 22:39:18  No: 22840

タイマーで一定時間ごとに
バックグラウンドで処理させるために
スレッドで処理を行っています。

前回の処理が終了していない場合には
処理をスキップするようにしたいのですが
どうすればよいのでしょうか?

イメージ的には以下のようになるのですが・・・

var
  MyThread: TMyThread

procedure TFormMain.Timer(Sender: TObject);
begin
  if  MyThread = Nil then MyThread := TMyThread.Create;
end;

procedure Terminate(Sender: TObject);
begin
  Self.Free;
  Self := Nil
end;


ハイジ  2006-08-04 22:41:24  No: 22841

もしくは、フリーされているかどうかをチェックする
関数などがあればよいのですが・・・

イメージ的には以下のような・・・
if CheckFree(MyThread) then begin
  MyThread := TMyThread.Create;
end;


風来坊  2006-08-05 09:33:43  No: 22842

スレッドが終了すると OnTerminate イベントが発生するので、
これで何とかなると思うのですが…


えーと  2006-08-05 10:34:31  No: 22843

> Self := Nil

じゃなくて 

MyThread := nil;

とすると

if Assigned(MyThread) then begin

で判定できるのでは?


まさ  2006-08-19 02:36:43  No: 22844

1つのインスタンスしか存在させたくないのですよね。
呼出し側で判定しないで、Singletonパターンで呼出し先で管理させては
どうですか?  タイミングの問題とか考えるとこの方が、安全だと思います。

例)スレッド側
unit Unit2;

interface

uses
  Classes, SysUtils, Windows;

type
  TMyThread = class(TThread)
  private
    { Private 宣言 }
    FCnt: Integer;
    procedure UpdateCaption;
  protected
    { protected 宣言 }
    procedure Execute; override;
  public
    { Public 宣言 }
    class function  GetInstance(reateSuspended: Boolean): TMyThread;
    constructor Create(reateSuspended: Boolean);
    destructor Destroy; override;
  end;

implementation

uses
  Unit1;

var
  Singleton: TMyThread;

{ MyThread }

procedure TMyThread.Execute;
begin
  { ToDo : スレッドとして実行したいコードをここに記述 }
  while not Terminated do
  begin
    Synchronize(UpdateCaption);
    Sleep(100);
  end;
  Free;
end;

procedure TMyThread.UpdateCaption;
begin
  Form1.Caption := IntToStr(FCnt);
  inc(FCnt);
end;

class function TMyThread.GetInstance(reateSuspended: Boolean): TMyThread;
begin
  // インスタンスを常に1つにする。
  if not Assigned(Singleton) then
  begin
    Singleton := TMyThread.Create(reateSuspended);
  end;
  Result := Singleton;
end;

constructor TMyThread.Create(reateSuspended: Boolean);
begin
  inherited Create(reateSuspended);
  FCnt := 0;
end;

destructor TMyThread.Destroy;
begin
  Singleton := nil;
  inherited;
end;

end.

呼出し側

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Db, DBTables, StdCtrls, Unit2;

type
  TForm1 = class(TForm)
    btnStart: TButton;
    btnEnd: TButton;
    procedure btnStartClick(Sender: TObject);
    procedure btnEndClick(Sender: TObject);
  private
    { Private 宣言 }
    FMyThread: TMyThread;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.btnStartClick(Sender: TObject);
begin
  FMyThread := TMyThread.GetInstance(False);
end;

procedure TForm1.btnEndClick(Sender: TObject);
begin
  FMyThread.Terminate;
end;

end.


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

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






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