私はTParallelを持っています。 &ループのため。このループでは、TMyClassオブジェクトを作成して使用して計算を行います。結果はResultListに格納されます。TParallel。&Forループでスレッドセーフなオブジェクトのデータとメソッドを使用する方法?
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;
私のコード例が動作します。しかし、それが正しいのかどうかは分かりませんし、いつもうまくいくでしょう。
メソッドMyClass.DoCalculationは、プログラムの開始時に作成されるTMyCommonClassオブジェクトのDoCalculationメソッドを呼び出します。
TMyClassはループごとに作成され、破棄されます。しかし、TMyCommonClassオブジェクトは一度しか存在しないため、異なるスレッドは並列にアクセスします。
私はTMyCommonClassに同期処理をせずに書き込むことはできませんが、データの読み取りとメソッドの使用についてはわかりません。
質問は以下のとおりです。
それはTMyCommonClassオブジェクトからデータを読み取るためにOKですか?
TMyCommonClassは、TListの子孫です。 Items [i]を使用してデータを読み取ることはできますか?
TMyCommonClass.DoCalculationを使用した私の例のように、TMyCommonClassのメソッドを呼び出すことはできますか?ここでローカル変数とメソッドパラメータはどうなりますか?スレッドセーフであるように、すべてのスレッドがローカル変数とメソッドパラメータのための独自のメモリ空間を確保することが保証されていますか?