Delphi 無名メソッド(無名関数)で簡単スレッド + OnTerminate

無名メソッドで、簡単使い捨て?スレッド
Caption := 'Wait...';
TThread.CreateAnonymousThread(
    procedure
    begin
        Sleep(3000);
        TThread.Synchronize(TThread.CurrentThread,
            procedure()
            begin
                Caption := 'Done';
            end);
    end).Start;
CreateAnonymousThread メソッドは、
Suspend = True
FreeOnTerminate = True
で、Thread を生成するので、Start メソッドを付けてスレッドを開始させるだけ

【追記】
OnTerminate も無名メソッドで記載してみる
type
    TNotifyEventProc = reference to procedure(Sender: TObject);
// -------------
procedure TForm1.Button1Click(Sender: TObject);
    procedure MethRefToMethPtr(const MethRef; var MethPtr);
    type
        TVtable = array [0 .. 3] of Pointer;
        PVtable = ^TVtable;
        PPVtable = ^PVtable;
    begin
        TMethod(MethPtr).Code := PPVtable(MethRef)^^[3];
        TMethod(MethPtr).Data := Pointer(MethRef);
    end;

    function MakeNotify(const Proc: TNotifyEventProc): TNotifyEvent;
    begin
        MethRefToMethPtr(Proc, Result);
    end;
begin
    with TThread.CreateAnonymousThread(
        procedure
        begin
            // スレッドで処理する内容
            Sleep(1000);
            TThread.Synchronize(TThread.CurrentThread,
                procedure()
                begin
                    Caption := 'Start';
                end);
            Sleep(2000);
        end) do begin

        OnTerminate := MakeNotify(
            procedure(Sender: TObject)
            begin
                // OnTerminate で処理する内容
                Caption := 'Finish';
            end);
        Start;
    end;
end;
with でくくって、OnTerminate へイベントを投入してみた(TThread型へ入れたほうが見やすい?)ワケですが一筋縄ではいきません
当初、こちらを参考にしていましたが、64bitでコンパイルすると正しく動作しないため、こちらも参考にして、MethRefToMethPtr と MakeNotify 関数(汎用的に使えるので、別に宣言してもよい)を挟んでます

OnTerminate って、メインスレッドで実行されるので Synchronize は必要ないんですね(Delphiのヘルプに記載されてました)

コメント