タイマーで一定時間ごとに
バックグラウンドで処理させるために
スレッドで処理を行っています。
前回の処理が終了していない場合には
処理をスキップするようにしたいのですが
どうすればよいのでしょうか?
イメージ的には以下のようになるのですが・・・
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;
もしくは、フリーされているかどうかをチェックする
関数などがあればよいのですが・・・
イメージ的には以下のような・・・
if CheckFree(MyThread) then begin
MyThread := TMyThread.Create;
end;
スレッドが終了すると OnTerminate イベントが発生するので、
これで何とかなると思うのですが…
> Self := Nil
じゃなくて
MyThread := nil;
とすると
if Assigned(MyThread) then begin
で判定できるのでは?
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.
ツイート | ![]() |