Спасибо! Я выложу еще один вопрос с кодом в качестве примера! Я буду рассчитывать на нашу помощь снова, если это возможно!
ужно создать несколько iTasks, которые будут заполнять один и тот же массив в разных позициях. Поскольку код, который нужно выполнить для каждой Задачи, одинаков, я решил создать массив iTasks и создал 4 задачи. У меня возникла проблема при передаче параметров в основную процедуру внутри iTask. когда я использую переменные в качестве параметров, учитываются только значения последней созданной задачи. Когда я передаю параметры как значения (жестко запрограммированные), они учитывают все значения для каждой задачи. Пожалуйста, смотрите мой код:
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;
==> Этот метод ниже, BTHardCodedClick, дает ожидаемый результат. Он заполняет массив соответственно. НО это жестко запрограммировано при создании 4 iTasks и при передаче параметров в ProcA. Я не хочу реализовывать этот способ!
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;
===> Следующий метод - тот, который я хочу реализовать, НО он не работает!, Потому что он не заполняет массив. Похоже, что выполняется только последний iTask "PTasks [indtask]".
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.
Я не могу понять, почему вызов procA (vfirst, vlast, vsize, indtask, varray) внутри iTask не учитывает значения параметров vfirst, vlast. Заранее спасибо за вашу помощь !