Obtenga un resultado de función de forma asíncrona en Delphi usando Omni Thread Library

Estoy tratando de llamar a una función desde otra unidad / clase que tomaría algún tiempo en realizar la tarea y devolvería un valor de cadena. No pude encontrar una buena referencia algo similar a C # async-wait como enfoque simple en Delphi. Usar la biblioteca Omni Thread me parece una buena idea.

Un simple ejemplo será un gran comienzo para mí.

Enfoque de muestra:

procedure TForm1.button1Click(Sender: TObject);
begin
  // notify before starting the task
  memo1.Lines.Add('calling a asynchronous function..');

  // call to the function that takes some time and returns a string value
  memo1.Lines.Add(GetMagicString);

  // notify that the task has been completed
  memo1.Lines.Add('Results fetched successfully.');
end;

Aquí la funciónGetMagicString debe procesar el resultado de forma asincrónica. Una vez que se obtiene el resultado, solo entonces el programa debe notificar que la tarea se ha completado. Por cierto, estoy usando Delphi-XE.

Edit1: Esto es lo que probé. Pero todavía no puedo encontrar la manera correcta de hacer el trabajo. El problema es cómo devolver el valor.

  .....
    private
      ResultValue: IOmniFuture<string>;
    .........
    .....


    function TForm1.FutureGet: string;
    begin
      Sleep(3000);
      Result := 'my sample magic string response ' +  IntToStr(Random(9999));
    end;

    procedure TForm1.FutureGetTerminated;
    begin
      // This code fired when the task is completed
      memo1.Lines.Add(ResultValue.Value);
    end;

    function TForm1.GetMagicString: string;
    begin
      ResultValue := Parallel.Future<string>(FutureGet,
            Parallel.TaskConfig.OnTerminated(FutureGetTerminated));

    end;

Aquí, usando Result: = ResultValue.Value alimenta la IU.

Edit2

Hice cambios según la respuesta proporcionada.

Código MainForm: unidad Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Unit2;



type
  TForm1 = class(TForm)
    memo1: TMemo;
    button1: TButton;
    procedure button1Click(Sender: TObject);
  private
    FOnStringReceived: TMyEvent;
    procedure StringReceived(const AValue: string);
    property OnStringReceived: TMyEvent read FOnStringReceived write FOnStringReceived;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


procedure TForm1.button1Click(Sender: TObject);
var
  MyObject: TMyClass;
begin
  // notify before starting the task
  memo1.Lines.Add('calling a asynchronous function..');

  // call to the function that takes some time and returns a string value
  MyObject := TMyClass.Create;
  OnStringReceived := StringReceived;
  try
    MyObject.GetMagicStringInBackground(OnStringReceived);
  finally
    MyObject.Free;
  end;
end;


procedure TForm1.StringReceived(const AValue: string);
begin
  memo1.Lines.Add(AValue);

   // notify that the task has been completed
  memo1.Lines.Add('Results fetched successfully.');
end;
end.

Otro código de unidad: unit Unit2;

interface

uses SysUtils, OtlTask, OtlParallel, OtlTaskControl;

type
  TMyEvent = procedure(const aValue: string) of object;

type
  TMyClass = class
  private
    FOnStringReceived: TMyEvent;
    function GetMagicString: string;
  public
    procedure GetMagicStringInBackground(AEvent: TMyEvent);
end;

implementation

{ TMyClass }

function TMyClass.GetMagicString: string;
begin
  Sleep(3000);
  Result := 'my sample magic string response ' +  IntToStr(Random(9999));
end;

procedure TMyClass.GetMagicStringInBackground(AEvent: TMyEvent);
var
  theFunctionResult: string;
begin
  Parallel.Async(
    procedure
    begin
      theFunctionResult := GetMagicString;
    end,

    Parallel.TaskConfig.OnTerminated(
    procedure (const task: IOmniTaskControl)
    begin
      if Assigned(AEvent) then
        AEvent(theFunctionResult);
    end)
  );
end;
end.

Sí, el código funciona como se esperaba. Solo quiero saber si esta es la mejor manera de hacer lo que realmente quiero realizar.

Respuestas a la pregunta(1)

Su respuesta a la pregunta