program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
  System.SysUtils, Threading;
begin
  try
    { TODO -oUser -cConsole メイン : ここにコードを記述してください }
    TParallel.For(0,9,
      procedure(i: integer)
      begin
        Writeln(i);
      end);
    Writeln('end');
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
これは私が
for var i:=0 to 9 do
begin
  Writeln(i);
end;
を並列処理に書き換えたくて作成したコードですが
実際には違った処理に終わります
どなたか解説をしていただけませんでしょうか。
https://docwiki.embarcadero.com/RADStudio/Sydney/ja/%E4%B8%A6%E5%88%97%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0_%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE_TParallel.For_%E3%81%AE%E4%BD%BF%E7%94%A8
>並列ループ内で、オペレーションをスレッドセーフのオペレーションに変換しなければなりません。System.SyncObjs ユニットのメンバー(TInterlocked メソッドなど)を使用することができます。
オンラインヘルプを見てご指摘のメンバー利用法が思いつかなかったのでこちらに投稿する以前にTThread.Synchronizeを用いてメインスレッドにアクセスを考えておりました。ウェブで調査するとTTaskで囲うような記述でなければ動作が呈するということでその通り回避策をとりましたが実行に難がありましたので質問させていただいた次第です。
それ以外に具体的な解決法があればご提示ください。よろしくお願いいたします。
使用先は複雑なアプリケーションですので複数回答があれば柔軟な方法を推奨してくださいますと助かります。
var
  CS: TRTLCriticalSection;
begin
   InitializeCriticalSection(CS);
  try
    { TODO -oUser -cConsole メイン : ここにコードを記述してください }
    TParallel.For(0,9,
      procedure(i: integer)
      begin
        EnterCriticalSection(CS);
        Writeln(i);
        LeaveCriticalSection(CS);
      end);
    Writeln('end');
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
   DeleteCriticalSection(CS);
end.
AAAAA  様、ご回答感謝します。初めてぐらいにTParallel.Forを動かした気がします。
私のソフトウェアでの応用も考えましたが、元来ループ箇所が少ない並列処理の恩恵を受けづらいコードだったのかもしれません。
題名にある問題は独力で解決できないよい解法が与えられているので質問は解決にして閉じさせていただきます。
相談に応じてくださりありがとうございました。
| ツイート |   |