4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Delphi][小ネタ] TThread を継承しないで簡単にスレッドを使いたい

Posted at

TThread を使った並列処理

TThread は Delphi 上でプラットフォームの Thread を抽象化したクラスです。

TThread を使えば簡単に並列処理を実装できますが、正統なやり方だとちょっと面倒…
記述量を減らしつつも、見やすくなる方法を紹介します。

TThread を継承する(正統な方法)

TThread を継承してオリジナルの Thread を作れば、独自のスレッドを作成できます。

例えば ↓ こんな感じです。

type
  TSampleThread = class(TThread)
  protected
    procedure Execute; override;
  end;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FThread: TSampleThread;
  end;

implementation

procedure TSampleThread.Execute;
begin
  while not Terminated do
  begin
    // 何か時間の掛かる処理
  end;
end;

procedure TForm1.FormCreate;
begin
  FTherad = TSmapleThread.Create;
  FTherad.FreeOnTerminate := True;
  FTherad.Start;
end;

クラス定義とか沢山かかないといけなくて面倒い…

CreateAnonymousThread を使う

TThread にはクラスを定義しなくても良い匿名メソッドを定義できる CreateAnonymousThread というメソッドがあります。
例えば ↓ のように使えます。便利~

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FThread: TThread;
  end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // Thread 内で自分にアクセスするため変数を定義する
  // この変数はローカル変数だが削除されない (下記 note 参照)
  var Thread = TThread.CreateAnonymousThread(
    procedure
    begin
      while not Thread.CheckTerminated do
      begin
        // 何か時間の掛かる処理
      end;
    end
  );

  FThread := Thread;
  FTherad.FreeOnTerminate := True;
  FTherad.Start;
end;

ローカル変数の生存期間が延びる件については下記参照
無名メソッド変数のバインディング

でもでも、CreateAnonymousThread の中に直接コードを書いたら、何十行とか何百行とかになったとき見通しの悪いコードになりそう(FormCreate が何百行にもなってしまう…)

別クラスで定義する

CreateAnonymousThread の手軽さと、TTherad 継承コードの読みやすさ、どっちも欲しい!

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private var
    FThread: TThread;
  private
    procedure ThreadMain;
  end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FThread := TThread.CreateAnonymousThread(
    procedure
    begin
      ThreadMain; // TForm1 に定義してあるメソッドを呼ぶだけにする
    end
  );
  FThread.Start;
end;

// Thread のメイン処理を TForm1 側に記述する
procedure TForm1.ThreaMain;
begin
  FThread.FreeOnTerminate := True;
  while not FThread.Terminated do
  begin
    // 何か時間の掛かる処理
  end;
end;

こんな風に TForm1 側に処理を逃がしてやれば、CreateAnonymousThread の中身を肥大化させずにコードを書けます。
しかも、TForm1 側の変数やプロパティにもアクセス自在!
(ただし、GUI 部分はメインスレッドで動かす必要があったり、別の場所からアクセスがある変数などでは排他制御が必要)

便利~

まとめ

Thread を操りたいけど継承して作るほどでもないな~継承して作るの面倒だな~っていうとき、使ってみてください。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?