[PR]
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
簡単に別スレッドで処理
Delphiで別スレッドを使って処理を行う場合TThreadクラスの継承クラスを作成して行うのが一般的ですが、その際必要なパラメーターをいちいちスレッドクラスに渡したりする必要が出てきたりします。
(それが面倒になってグローバル変数を使ってみたり、自身のポインタを渡してみたり^^)
なので簡単に別スレッド処理を使えるように考えてみました。
//簡単スレッドクラス
unit EasyThread;
interface
uses
Windows, Classes;
type
TThreadProc = procedure of Object;
TThreadSync = procedure of Object;
TEasyThread = class(TObject)
private type
TPrivatetThread = class(TThread)
private
FThreadProc : TThreadProc;
public
constructor Create( ThreadProc : TThreadProc );
protected
procedure Execute; override;
end;
private
FThread : TPrivatetThread;
function GetTerminated: Boolean;
public
constructor Create( ThreadProc : TThreadProc );
destructor Destroy; override;
procedure Synchronize( SyncProc : TThreadSync);
procedure Terminate;
procedure WaitFor;
property Terminated : Boolean read GetTerminated;
end;
implementation
{ TEasyThread }
constructor TEasyThread.Create( ThreadProc : TThreadProc );
begin
FThread := TPrivatetThread.Create(ThreadProc);
end;
destructor TEasyThread.Destroy;
begin
if Assigned(FThread) then FThread.Free;
inherited;
end;
function TEasyThread.GetTerminated: Boolean;
begin
result := FThread.Terminated;
end;
procedure TEasyThread.Terminate;
begin
if Assigned(FThread) then FThread.Terminate;
end;
procedure TEasyThread.WaitFor;
begin
try
if Assigned(FThread) then FThread.WaitFor;
except end;
end;
procedure TEasyThread.Synchronize(SyncProc: TThreadSync);
begin
if Assigned(FThread) then FThread.Synchronize(SyncProc);
end;
{ TEasyThread.TPrivatethread }
constructor TEasyThread.TPrivatetThread.Create(ThreadProc: TThreadProc);
begin
inherited Create(False);
FThreadProc := ThreadProc;
end;
procedure TEasyThread.TPrivatetThread.Execute;
begin
if Assigned(FThreadProc) then FThreadProc;
end;
end.
・簡単スレッドクラスを使う例
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, EasyThread;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
Count : Integer;
ET : TEasyThread;
public
procedure ThreadProcedure; //別スレッドから呼ばれる
procedure VCL; //別スレッドからVCLにアクセスする場合に使う
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
ReportMemoryLeaksOnShutdown := True;
if not Assigned(ET) then ET := TEasyThread.Create(ThreadProcedure);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
if Assigned(ET) then ET.Free;
end;
procedure TForm1.ThreadProcedure;
begin
//別スレッドから呼ばれる関数内でループ処理を行う場合は、かならずTerminated変数を監視する
while not ET.Terminated do begin
Inc(Count);
//VCLを使う場合はSynchronizeから呼び出す
ET.Synchronize(VCL);
Sleep(1);
if Count = 3000 then Break;
end;
end;
procedure TForm1.VCL;
begin
Label1.Caption := IntToStr(Count);
end;