I have a TParallel.&For loop. In this loop I create and use a TMyClass object to do the calculation. The result is stored in ResultList.
type
TMyCommonClass=class(TList<Real>)
private
function DoCalculation(const AValue: Integer): Real;
end;
type
TMyClass=class(TList<Real>)
private
MyCommonClass: TMyCommonClass;
function DoCalculation(const AValue: Integer): Real;
end;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
MyCommonClass: TMyCommonClass;
end;
function TMyCommonClass.DoCalculation(const AValue: Integer): Real;
var
r: Real; //some local vars
begin
r:=Items[AValue]*100; //some example calculations using local vars
Result:=r;
end;
function TMyClass.DoCalculation(const AValue: Integer): Real;
begin
Result:=MyCommonClass.DoCalculation(AValue);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
MyCommonClass:=TMyCommonClass.Create;
for i := 0 to 1000000 do //add some example data to the list
begin
MyCommonClass.Add(i*0.01);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
ALock: TCriticalSection;
LoopResult: Tparallel.TLoopResult;
ResultList: TList<Real>;
i: Integer;
begin
ResultList:=TList<Real>.Create;
try
ALock:=TCriticalSection.Create;
try
LoopResult:=TParallel.&For(0, 100000,
procedure(AIndex: Integer)
var
MyClass: TMyClass;
r: Real;
begin
MyClass:=TMyClass.Create;
MyClass.MyCommonClass:=MyCommonClass;
try
r:=MyClass.DoCalculation(AIndex);
begin
ALock.Enter;
try
ResultList.Add(r);
finally
ALock.Leave;
end;
end;
finally
MyClass.Free;
end;
end);
finally
ALock.Free;
end;
ResultList.Sort;
//show the result list
for i := 0 to ResultList.Count-1 do
begin
Memo1.Lines.Add(FloatToStr(ResultList[i]));
end;
finally
ResultList.Free;
end;
end;
My example code works. But I am not sure if it is correct and will always work.
The method MyClass.DoCalculation calls the DoCalculation method of a TMyCommonClass object which is created at program start.
The TMyClass is created and destroyed for every loop. However the TMyCommonClass object only exist once so the different threads will access it in parallel.
I understand that I cannot write to TMyCommonClass without taking care of synchronisation but I am not sure about reading data and using methods.
The questions are:
Is it OK to read data from the TMyCommonClass object?
TMyCommonClass is a descendant of TList. Is it OK to read data using Items[i]?
Is it OK to call a method of TMyCommonClass like I do in my example with TMyCommonClass.DoCalculation? What happens here to the local variables and the method parameters? Is it guaranteed that every thread gets it own memory space for the local variables and method parameters so that it is thread safe?