How to pass parameters to run on a Delphi thread

Asked

Viewed 1,450 times

2

I’m having trouble assigning a variable value inside a Thread Run.

need to assign a value to the variable Name through the Fname that is inside the execute of a thread.

follows the example I’m trying to make.

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.
  • 1

    Why did you edit the question that way ?

1 answer

1

First of all, I see no links between FName and Name. For this you need to implement this section in your class:

public
  property Name: string read FName write FName;

With this you will be telling the compiler, that 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 variable FName directly, but in more complex cases where the code is object-oriented, it is necessary to create this public.

The second question is that in this example of yours, the Return will be Teste1 and Teste2, but I believe you’re expecting a Teste3 in place of Teste2, right ?

If that’s the case, then what happens is this:

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`

That’s right! , your WriteLn(Name); this coming before the Execute of your Thread. Remember, you are working with parallel processes.

Follow 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.
  • @Daniloalves, based on your comment, I reiterate. Your variable Name has nothing to do with the FName. No create from your thread o FName receives Name, but at no time the Name which is in the kind out, gets a value back. That is, you do nothing with the variable Name. If you want to keep the code the way it is ( confused ), you just do the Name := Test.FName before displaying it in the console log.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.