iTask - como usar variáveis como parâmetros para o procedimento TTask

Preciso criar um número de iTasks que preencherão a mesma matriz em posições diferentes. Como o código a ser executado para cada tarefa é o mesmo, decidi criar uma matriz de iTasks e criei 4 tarefas. Eu tive um problema ao passar parâmetros para o procedimento principal dentro do iTask. quando eu uso variáveis como parâmetros, apenas os valores da última tarefa criada estão sendo considerados. Quando passo os parâmetros como valores (codificados), ele respeita todos os valores de cada tarefa. Por favor, veja meu código:

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, 
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  UNTThreads, Vcl.StdCtrls,
  System.Threading ;

type
 Vet         = array of integer;

type
  TFMThreadArray = class(TForm)
    EDTArraySize: TEdit;
    EDTNumberofThreads: TEdit;
    Memo1: TMemo;
    LBArraySize: TLabel;
    LBThreads: TLabel;
    BTUsingForLoop: TButton;
    EDTThread: TEdit;
    BTHardCoded: TButton;

    procedure BTUsingForLoopClick(Sender: TObject);
    procedure BTHardCodedClick(Sender: TObject);

  private
    { Private declarations }


    procedure  ProcA ( Const  pin, pfin, Psize, Ptask  : integer;
                       Var   Parray : vet);

  public
    { Public declarations }
  end;

var
  FMThreadArray: TFMThreadArray;

implementation

{$R *.dfm}


// Procedure to be called by each iTask    
    procedure TFMThreadArray.ProcA ( Const  pin, pfin, Psize, Ptask  : integer;
                                      Var   Parray : vet);
    var
        vind : integer;

    begin
          for vind := pin to pfin do
          begin
               Parray[vind]   := vind * 10;
          end;
    end;

==> Este método abaixo, BTHardCodedClick, produz o resultado esperado. Ele preenche a matriz de acordo. MAS é codificado na criação de 4 iTasks e na passagem de parâmetros no ProcA. Eu não quero implementar dessa maneira!

procedure TFMThreadArray.BTHardCodedClick(Sender: TObject);

var
    varray                   : vet;
    ind, indtask             : Integer;
    Ptasks                   : array of iTask;

begin
     memo1.Clear;

     SetLength(PTasks,Strtoint(EDTNumberofThreads.text));
     SetLength(varray,StrToint(EDTarraysize.text));

     // fill array with a initial value -2
     for ind := Low(varray) to High(varray) do
            varray[ind] :=-2;


     // when call ProcA passing values parameters it works propperly
     PTasks[0] := TTask.Create( procedure
                                      begin
                                             ProcA(0,3,16,0,varray) ;
                                      end
                                     ) ;

     PTasks[1] := TTask.Create( procedure
                                      begin
                                             ProcA(4,7,16,1,varray) ;
                                      end
                                     ) ;

     PTasks[2] := TTask.Create( procedure
                                      begin
                                             ProcA(8,11,16,2,varray) ;
                                      end
                                     ) ;

     PTasks[3] := TTask.Create( procedure
                                      begin
                                             ProcA(12,15,16,3,varray) ;
                                      end
                                     ) ;


     for Indtask := Low(Ptasks) to High(Ptasks) do
         Ptasks[Indtask].Start;

     TTask.WaitForAll(Ptasks);

     memo1.Clear;
     memo1.Lines.Add(' ============== Creating TASKs with hard-coded parameters ===============');
     memo1.lines.add(' Array size : '        + EDTArraySize.text +
                      ' number of Tasks : ' + EDTNumberofThreads.text);
     memo1.Lines.Add(' =========================================================');

     for ind := Low(varray) to High(varray) do
          memo1.Lines.Add(' Array position  : '    + Format('%.3d',[ind])  +
                          '   content  : ' + varray[ind].ToString   );

end;

===> O método a seguir é o que eu quero implementar, mas não está funcionando!, Porque não está preenchendo a matriz. Parece que apenas o último iTask "PTasks [indtask]" está sendo executado.

procedure TFMThreadArray.BTUsingForLoopClick(Sender: TObject);
var
    varray                           : vet;
    Ptasks                           : array of iTask;
    vind, indtask, vslice            : Integer;
    vfirst, vlast, vthreads, vsize   : Integer;

begin

     vthreads := Strtoint(EDTNumberofThreads.text);
     vsize    := StrToint(EDTArraysize.text);

     SetLength(PTasks,vthreads);
     SetLength(varray,vsize);

     for vind := Low(varray) to High(varray) do
            varray[vind]:=-33;

     vslice := Length(varray) div vthreads;


     for indtask := Low(PTasks) to High(PTasks) do
     begin
          vfirst := indtask       * vslice;
          vlast  := (indtask + 1) * vslice - 1;

          if (Length(varray) mod vthreads <> 0) and (indtask = High(Ptasks)) then
               vlast := HIgh(varray);

          PTasks[indtask] := TTask.Create( procedure
                                            begin
                                                  procA(vfirst,vlast,vsize,indtask,varray) ;
                                            end
                                           ) ;
     end;

     // Starting all Tasks
     for Indtask := Low(Ptasks) to High(Ptasks) do
         Ptasks[Indtask].Start;

     // Waits until all Tasks been concluded
     TTask.WaitForAll(Ptasks);

     memo1.Clear;
     memo1.Lines.Add(' =============  Using For Loop to create the TASKs =====================');
     memo1.lines.add(' Array size : '        + EDTArraySize.text +
                      ' number of Tasks : ' + EDTNumberofThreads.text);
     memo1.Lines.Add(' =========================================================');


     for vind := Low(varray) to High(varray) do
         memo1.Lines.Add(' Array position  : '    + Format('%.3d',[vind])  +
                         '   content  : '         + varray[vind].ToString   );

end;

end.

Não consigo entender por que uma chamada para procA (vfirst, vlast, vsize, indtask, varray) dentro do iTask não está considerando os valores dos parâmetros vfirst, vlast. Agradeço antecipadamente por sua ajuda !

questionAnswers(1)

yourAnswerToTheQuestion