読んで字の如く。
#前置き
DelphiのRTLは .NET Framework を後追いしている印象があり、
TTask
クラスを始めとした並列プログラミングライブラリも
割と最近のバージョン(XE7)で追加されました。
しかし基盤となる技術が異なる、設計思想が異なる等の理由で
メソッドや記述方法が違っていたり、そもそも機能がなかったりします。
#継続処理は必要でしょ
並列処理を実装していくと、たいてい時間のかかる処理の前後で
UI操作を行ったり処理順を意識する場面が出てきたりします。
こういうとき .NET では ContinueWith
メソッドを使用しますが、
残念ながらDelphiのTTask
クラスにはありません。
ということで作ってみました。
ダウンロード(MITライセンス)
TTask
クラスのヘルパーとして実装されているので
usesするだけで以下のように使用可能です。
メソッドチェーンももちろんOK。
//----------
uses
System.Threading, WS.Threading;
//----------
procedure TForm1.Button1Click(Sender: TObject);
begin
Button1.Enabled := false;
Label1.Text := '処理1...';
// 時間のかかる処理(別スレッド)
TTask.Run(procedure
begin
TThread.Sleep(5000);
//raise EInvalidOperation.Create('例外テスト');
end)
// 継続処理のためUI更新(前スレッド完了時のみ。UIスレッド)
.ContinueWith(procedure(t: ITask)
begin
Label1.Text := '処理2...';
end, [TTaskContinuationOption.OnCompleted, TTaskContinuationOption.Synchronize])
// 時間のかかる継続処理(前スレッド完了時のみ。別スレッド)
.ContinueWith(procedure
begin
TThread.Sleep(5000);
end, [TTaskContinuationOption.OnCompleted])
// 後処理(UIスレッド)
.ContinueWith(procedure
begin
Button1.Enabled := true;
Label1.Text := '完了';
end, [TTaskContinuationOption.Synchronize])
;
end;
ContinueWith
に指定するプロシージャは前のタスクをパラメータに受け取ることもできます。
TTask.Run
メソッドだけでなくTTask.Future<T>
メソッドも継続可能になっていますが、
ContinueWith
自体は戻り値を返せません。
本当はやりたかったけどインタフェースにジェネリックメソッドを定義できないので
断念しました…。
Delphi 10.1以降で動作確認しましたが
XE7以降なら動くかも。動いたら報告頂けると幸い。
またVCL、FMXのすべてのプラットホーム(Linux含む)で動作します。
ソースはMITライセンスに基づいて自由にしてもらって構いませんが、
バグ報告や機能追加のフィードバックもらえると喜びます。