Search code examples
multithreadingdelphidelphi-xe2

Passing a value to onTerminate with AnonymousThread


I have a running threading application that is computing some longer calculations.

procedure TForm.calculationInThread(value: Integer);
var aThread : TThread;
begin
  aThread :=
    TThread.CreateAnonymousThread(
      procedure
      begin
        myCalculation(value);           
      end
    );
  aThread.FreeOnTerminate := True;
  aThread.OnTerminate := self.calculationInThreadEnd;
  aThread.Start;
end; 

And an implementation of calculationInThreadEnd;

procedure TForm.calculationInThreadEnd(Sender: TObject);
begin
   doSomething;
end;

I may miss just something stupid, but how to pass a value to calculationInThreadEnd? I found

TThread.SetReturnValue(value);

but how do i access that in the onTerminate call?

Solution

type THackThread = class(TThread);

procedure TForm1.calculationInThreadEnd(Sender: TObject);
var Value: Integer;
begin
    Value := THackThread(Sender as TThread).ReturnValue;  
end;

Solution

  • The Sender parameter of the OnTerminate event is the thread object. So you can do this:

    aThread :=
      TThread.CreateAnonymousThread(
        procedure
        begin
          myCalculation(value);           
          TThread.SetReturnValue(...);
        end
      );
    

    Then in the OnTerminate event handler you can do:

    procedure TForm.calculationInThreadEnd(Sender: TObject);
    var
      Value: Integer;
    begin
      Value := (Sender as TThread).ReturnValue;
    end;
    

    Update

    The return value property is protected so you'll need to use the protected hack to gain access to it.