Utilisation de TTask de la bibliothèque de programmation parallèle
Remonter à Utilisation de la bibliothèque de programmation parallèle
La bibliothèque de programmation parallèle fournit une classe TTask pour exécuter une ou plusieurs tâches en parallèle. Une tâche est une unité de travail à effectuer. La PPL fait l'association entre la tâche et le thread qui effectue la tâche, de sorte que vous pouvez exécuter plusieurs tâches en parallèle sans avoir à créer vos propres threads personnalisés ni à les gérer.
TTask crée et gère l'interaction avec des instances de ITask. ITask est une interface qui fournit un ensemble de méthodes et de propriétés pour démarrer, attendre, annuler et aussi une propriété pour l'état (Created, WaitingToRun, Running, Completed, WaitingForChildren, Canceled, Exception).
TTask fournit WaitForAll et WaitForAny pour attendre la fin de toutes les tâches ou d'une tâche. WaitForAll renvoie le résultat lorsque toutes les tâches sont terminées, tandis que WaitForAny vous indique que la première tâche est terminée. Par exemple, si vous avez deux tâches A et B qui durent respectivement 3 et 5 secondes, le temps d'attente avant d'obtenir un résultat est :
- Séquentiellement (sans utiliser TTask/ITask) = 8 secondes
- TTask.WaitForAny = 3 secondes
- TTask.WaitForAll = 5 secondes
L'exemple suivant utilise la méthode WaitForAll :
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;
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));
}
Une autre fonctionnalité de TTask consiste à empêcher le verrouillage de l'interface utilisateur lorsque vous voulez démarrer quelque chose en arrière-plan. L'exemple de code suivant montre comme exécuter une seule tâche et la démarrer :
procedure TFormThreading.Button1Click(Sender: TObject);
var
aTask: ITask;
begin
aTask := TTask.Create (procedure ()
begin
sleep (3000); // 3 seconds
ShowMessage ('Hello');
end);
aTask.Start;
end;
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);
}