01.09.2023, Vladimír Klaus, navštíveno 371x

Delphi

Pokud potřebuji paralelně zavolat nějaký výpočet a nakonec výsledek zobrazit třeba v Labelu, je to velice jednoduché, jak bylo detailněji ukázáno v tomto článku. Samozřejmě nemusí jít jen o zobrazení výsledku, ale zavolání třeba dalšího procesu. 

Jaký je rozdíl mezi TTask a TTask.Future v Delphi

Takže buď takto:

var myTask:=TTask.Create(procedure ()
  begin
    var i:=NarocnyVypocet;
    TThread.Queue (nil, procedure
      begin
        Label1.Caption:=i.ToString;
        LogujUkonceniVypoctu;
      end);
  end);
myTask.Start;

Nebo ještě jednodušeji takto:

TTask.Run(procedure
begin
  var i:=NarocnyVypocet;
  TThread.Queue(nil, procedure
  begin
    Label1.Caption:=i.ToString;
    LogujUkonceniVypoctu;
  end);
end);

K čemu nám ale může sloužit TFuture? V případě, že potřebujeme něco (paralelně) vypočítat a výsledek můžeme požadovat až v budoucnosti. TFuture totiž poskytuje výsledek/hodnotu. To je zajímavý koncept, ale také trochu ošidný. Následující kód provede onen náročný výpočet.

var fut: IFuture<smallint>;

fut:=TTask.Future<smallint>(
  function(): smallint
  begin
    result:=NarocnyVypocet;
  end
);

A pak někde jinde, někdy jindy se můžeme na výsledek dotázat, resp. ho použít.

procedure TMainForm.Button1Click(Sender: TObject);
begin
  Label1.Caption:=fut.Value.ToString;
end;

A co je zde tedy ošidného? No pokud hodnota ve chvíli, kdy jí požadujeme ještě není k dispozici (probíhá paralelní úloha), tak se aplikace (hlavní vlákno) zastaví a čeká na dokončení výpočtu. To zcela boří hlavní důvod paralelního zpracování - abychom neměli blokovanou hlavní aplikaci.

Tuto metodu tedy můžete využít v případě, že jste si jisti, že až se bude hodnota požadovat, tak již bude k dispozici, no a nebo tuto žádost opět obalit nějakým TTask, což už ale zcela ztrácí smysl.

Já TFuture využívám především jako pomocníka při startu aplikace, kdy se zjišťuje řada věcí, a absolutně nehrozí, že bychom je já nebo uživatel potřebovali ihned zobrazovat či využívat.