delphi.gif (306 バイト) スレッドの使い方


スレッドを使うとアプリケーションに同時に2つ以上の仕事をさせることができます。DelphiではTThreadから派生させたクラスをカスタマイズすることによってスレッドを使用します。

 

toach.gif (917 バイト) アプリケーションにスレッドを追加するには

  1. 「ファイル/新規作成」を実行して、新規作成タブから「スレッドオブジェクト」を選びます。
  2. OKボタンを押すとクラス名を入力するためのダイアログが現れるので、そのスレッドクラスの名前を入力します。
  3. OKボタンを押すとそのスレッドクラスを含む新しいユニットがプロジェクトに追加されます。

 

toach.gif (917 バイト) スレッドオブジェクトの作成と廃棄

スレッドを使うとき、最初にスレッドクラスをインスタンス化してスレッドオブジェクトを作成します。

thread := TMyThread.Create(False);

スレッドオブジェクトを廃棄するときは、Destroyメソッド(デストラクタ)を呼び出します。

thread.Destroy;

(注意)

後に出てくるExecuteメソッドが動作しているときデストラクタを呼び出すとアプリケーションがハングアップするので注意してください。また、スレッドオブジェクトがあるのに、アプリケーションを終了した場合も同様です。

 

toach.gif (917 バイト) スレッドに作業をやらせるには

スレッドに作業をやらせるには、Executeメソッドをオーバーライドします。スレッドオブジェクトを追加すると自動的にユニットにコードが追加されるので、Executeメソッドの中身を追加するだけでOKです。

スレッドの中からフォームに直接描画することはできません。Executeメソッドの中でSynchronizeメソッドを呼び出して間接的に行います。Synchronizeメソッドのパラメータには、その動作を行うメソッドを指定します。

追加されたスレッドオブジェクトのユニットで、いろいろなシステムユニットに含まれるオブジェクトや手続きを使うには、usesの下に必要なユニット(SysUtilsなど)を追加する必要があります。

 

delphi1.gif (322 バイト) 例 (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.