delphiでマルチスレッド同期を実装する方法

Delphiでは、TThread.Synchronizeメソッドにより、マルチスレッド同期を実現できます。

TThread.Synchronizeメソッドには2つの引数を受け取ります。1つ目の引数は匿名メソッドかメソッドポインタで、主スレッドで行うコードを指定します。もう1つの引数は配列で、匿名メソッドかメソッドポインタに渡される引数を表します。

以下は TThread.Synchronize メソッドを使用してマルチスレッドの同期方法を示したコード例です。

unit Main;

interface

uses
  System.Classes, System.SysUtils, Vcl.Forms, Vcl.StdCtrls;

type
  TMyThread = class(TThread)
  private
    FValue: Integer;
  protected
    procedure Execute; override;
  public
    constructor Create(AValue: Integer);
    property Value: Integer read FValue;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    procedure UpdateLabel(AValue: Integer);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyThread }

constructor TMyThread.Create(AValue: Integer);
begin
  inherited Create(True);
  FValue := AValue;
end;

procedure TMyThread.Execute;
begin
  // 在这里执行耗时的操作
  Sleep(5000);
  // 在主线程中更新界面
  TThread.Synchronize(nil,
    procedure
    begin
      Form1.UpdateLabel(Value);
    end);
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  MyThread: TMyThread;
begin
  MyThread := TMyThread.Create(10);
  MyThread.Start;
end;

procedure TForm1.UpdateLabel(AValue: Integer);
begin
  Label1.Caption := 'Value: ' + IntToStr(AValue);
end;

end.

上で示したコードの例では、ボタン Button1 をクリックすると、スレッド TMyThread を作成し、スレッド内で時間がかかる処理を実行し、TThread.Synchronize メソッドで Label1 の Caption プロパティを更新します。

注意、TThread.Synchronizeメソッドはブロックされ、スレッドはメインスレッドの実行が完了するまで待機してから続行する必要があります。したがって、メインスレッドで実行されるコードも時間のかかるものである場合、プログラムの応答性が低下する可能性があります。時間のかかる操作をバックグラウンドで実行する必要がある場合は、TThread.Queueメソッドを使用して非同期にインターフェイスを更新することをお勧めします。

bannerAds