How to pass parameters to run on a Delphi thread

2

I am having difficulty assigning a value of a variable within the Execute of a Thread.

I need to assign a value to the Name variable through FName that is within a thread's execution.

Here's an example I'm trying to do.

program Project2;

uses
  System.SysUtils, Classes;

type
  TTest = class(TThread)
  private
    var FName: string;
  protected
    procedure Execute; override;
  public
    constructor Create(const CreateSuspended: boolean; out AName: string);
  end;


{ TTest }
constructor TTest.Create(const CreateSuspended: boolean; out AName: string);
begin
  AName:= 'Test2';
  FName:= AName;
  inherited Create(CreateSuspended);
end;

procedure TTest.Execute;
begin
  FName:= 'Teste3';
end;


var
  Name: string;
  Test: TTest;
begin

  Name:= 'Teste1';
  WriteLn(Name);

  Test:= TTest.Create(False, Name);
  WriteLn(Name);

  ReadLn;
end.
    
asked by anonymous 07.02.2017 / 21:10

1 answer

1

First, I do not see links between FName and Name . For this you need to implement this snippet in your class:

public
  property Name: string read FName write FName;

With this you will be telling the compiler, that the Property Name , will be read and written as FName

In this case as the implementation is all done in the same unit, your main code will be layers to access the FName variable directly, but in more complex cases where code is object oriented, you need to create this property in public .

The second question is that in this example, Return will be Teste1 and Teste2 , but I believe you're expecting Teste3 instead of Teste2 , right?

If this is the case, what happens is as follows:

1) Você joga no console o valor 'Teste1'
2) Você Cria a Thread
3) O método 'create' da Thread alimenta o 'FName' com 'Teste2'
4) Você joga no console o valor de 'FName'
5) A Thread altera o valor de 'FName' para 'Teste3'

Exactly !, Your WriteLn(Name); is coming before the Execute of your Thread. Remember, you're working with parallel processes.

Here is the code set for better clarification:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}


uses
  System.SysUtils, Classes;

type
  TTest = class(TThread)
  private
    FName: string;

  protected
    procedure Execute; override;

  public
    property Name: string read FName write FName;

    constructor Create(const CreateSuspended: boolean);
  end;

var
  Test: TTest;
  { TTest }



constructor TTest.Create(const CreateSuspended: boolean);
begin
  FName := 'Test2';
  inherited Create(CreateSuspended);
end;



procedure TTest.Execute;
begin
  inherited;
  FName := 'Teste3';
end;


var
  Name: String;
begin

  Name := 'Teste1';
  WriteLn(Name);

  Test := TTest.Create(False);
  //Sleep(1000); // Este sleep vai fazer com que o Execute da thread consiga alterar o valor antes do WriteLn.

  Name := Test.Name;
  WriteLn(Name);

  ReadLn;

end.
    
08.02.2017 / 11:57