スレッドの使い方
スレッドを使うとアプリケーションに同時に2つ以上の仕事をさせることができます。DelphiではTThreadから派生させたクラスをカスタマイズすることによってスレッドを使用します。
アプリケーションにスレッドを追加するには
スレッドオブジェクトの作成と廃棄
スレッドを使うとき、最初にスレッドクラスをインスタンス化してスレッドオブジェクトを作成します。
例
thread := TMyThread.Create(False);
スレッドオブジェクトを廃棄するときは、Destroyメソッド(デストラクタ)を呼び出します。
例
thread.Destroy;
(注意)
後に出てくるExecuteメソッドが動作しているときデストラクタを呼び出すとアプリケーションがハングアップするので注意してください。また、スレッドオブジェクトがあるのに、アプリケーションを終了した場合も同様です。
スレッドに作業をやらせるには
スレッドに作業をやらせるには、Executeメソッドをオーバーライドします。スレッドオブジェクトを追加すると自動的にユニットにコードが追加されるので、Executeメソッドの中身を追加するだけでOKです。
スレッドの中からフォームに直接描画することはできません。Executeメソッドの中でSynchronizeメソッドを呼び出して間接的に行います。Synchronizeメソッドのパラメータには、その動作を行うメソッドを指定します。
追加されたスレッドオブジェクトのユニットで、いろいろなシステムユニットに含まれるオブジェクトや手続きを使うには、usesの下に必要なユニット(SysUtilsなど)を追加する必要があります。
例 (Eventにもスレッドの例があります。クリティカルセクションも参考にしてください)
つぎの例は、Startボタンを押すとスレッドがShape(矩形)を暗い青にしつづけます。Resetボタンを押すとShapeは白にもどるのですが、バックグランドでスレッドが暗い青に書き換えてしまうので、一瞬しか白くなりません。Stopボタンを押すとShapeは赤になり、スレッドはShapeが赤になったら停止します。この後、Resetを押すとShapeは白にもどり、また、Startを押すと前と同じように動きます。
UNIT1 (Main)
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs
, StdCtrls, ExtCtrls,Unit2;
type
TForm1 = class(TForm)
Shape1: TShape;
Start: TButton;
Stop: TButton;
White: TButton;
Edit1: TEdit;
procedure WhiteClick(Sender: TObject);
procedure StartClick(Sender: TObject);
procedure StopClick(Sender: TObject);
private
{ Private 宣言 }
thread: MyThread;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.WhiteClick(Sender: TObject);
begin
Shape1.Brush.Color := clWhite;
end;
procedure TForm1.StartClick(Sender: TObject);
begin
thread := MyThread.Create(False);
end;
procedure TForm1.StopClick(Sender: TObject);
begin
Shape1.Brush.Color := clRed;
end;
end.
UNIT2 (Thread Object)
unit Unit2;
interface
uses
Classes, Graphics, SysUtils;
type
MyThread = class(TThread)
private
{ Private 宣言 }
protected
procedure Execute; override;
procedure TobeRed;
end;
implementation
{注意: VCL のメソッド/関数/プロパティを扱うには、以下のように
Synchronize メソッドの引数として渡したメソッドの中から扱う必要があります。
Synchronize(UpdateCaption);
UpdateCaption の中では以下のように VCL を呼び出すことができます。
procedure MyThread.UpdateCaption;
begin
Form1.Caption := 'スレッドから書き換えました';
end; }
{ MyThread }
uses
Unit1;
procedure MyThread.Execute;
begin
{ スレッドとして実行したいコードをここに記述 }
while True do
begin
if Form1.Shape1.Brush.Color = clRed then Exit;
Synchronize(TobeRed);
end;
end;
procedure MyThread.TobeRed;
var
v, code: Integer;
begin
Form1.Shape1.Brush.Color := $808000;
Val(Form1.Edit1.Text, v, code);
Inc(v);
Form1.Edit1.Text := IntToStr(v);
end;
end.