並列プログラミング ライブラリの TTask の使用

提供: Appmethod Topics
移動先: 案内検索

並列プログラミング ライブラリの使用 への移動


並列プログラミング ライブラリ(PPL)には、1 つまたは複数のタスクを並列に実行するための TTask クラスが用意されています。タスクは、完了すべき作業の単位です。PPL では、タスクとそのタスクを実行するスレッドの関連付けを行うので、独自のカスタム スレッドを作成し管理しなくても、複数のタスクを並列に実行することができます。

TTask では、ITask のインスタンスとのやり取りを作成し管理します。ITask は、広範囲な StartWaitCancel へのメソッドやプロパティ、また Status のプロパティ(Created、WaitingToRun、Running、Completed、WaitingForChildren、Canceled、Exception)を提供するインターフェイスです。

TTask には、すべてまたは任意のタスクが完了するのを待つための、WaitForAllWaitForAny が用意されています。WaitForAll が、すべてのタスクの完了時に制御を返すのに対して、WaitForAny は最初に完了したタスクを通知します。たとえば、2 つのタスク A と B があり、それぞれ 3 秒と 5 秒かかる場合、結果が得られるまでの時間は次のとおりです:

次の例では、WaitForAll メソッドを使用しています:

Object Pascal:
 
procedure TFormThreading.MyButtonClick(Sender: TObject);
var 
 tasks: array of ITask; 
 value: Integer; 
begin 
 Setlength (tasks ,2); 
 value := 0; 

 tasks[0] := TTask.Create (procedure () 
   begin 
   sleep (3000); // 3 seconds 
   TInterlocked.Add (value, 3000); 
  end); 
 tasks[0].Start; 

 tasks[1] := TTask.Create (procedure () 
   begin 
   sleep (5000); // 5 seconds 
   TInterlocked.Add (value, 5000);
 end); 
 tasks[1].Start; 
 
 TTask.WaitForAll(tasks); 
 ShowMessage ('All done: ' + value.ToString); 
end;
C++:
void __fastcall TFormThreading::MyButtonClick(TObject *Sender)
{
   _di_ITask tasks[2];

   tasks[0] = TTask::Create(_di_TProc(new TCppTask(lvalue, 3000, Label1)));
   tasks[0]->Start());
   
   tasks[1] = TTask::Create(_di_TProc(new TCppTask(lvalue, 5000, Label1)));
   tasks[1]->Start());

   TTask::WaitForAll(tasks,(sizeof(tasks)/sizeof(tasks[0])-1));
   ShowMessage("All done! "+IntToStr(lvalue));
}

TTask のもう 1 つの機能は、何らかの処理をバックグラウンドで開始する場合にユーザー インターフェイスが動かなくなるのを避けることです。次のコード例では、単一のタスクを作成し開始する方法を示しています:

Object Pascal:
 
procedure TFormThreading.Button1Click(Sender: TObject);
var
 aTask: ITask;
begin
 aTask := TTask.Create (procedure ()
   begin
     sleep (3000); // 3 seconds
     ShowMessage ('Hello');
   end);
 aTask.Start;
end;
C++:
void __fastcall TFormThreading::Button1Click(TObject *Sender)
{
  Label1->Caption = "--";
  lvalue = 0;
  _di_ITask aTask = TTask::Create(_di_TProc(new TCppTask(lvalue,3000,Label1)));
  aTask-> Start();
  Label1->Caption =InToStr(lvalue);
}

関連項目