Как синхронизировать отображение процессора и выполнение циклов в Delphi Parallel.For?

#delphi

#delphi

Вопрос:

У меня есть Parallel.For() цикл в моей программе следующим образом:

 procedure TForm1.Button1Click(Sender: TObject);
var
  n,m:integer;
  handle: THandle;
begin
  //BeforeTest;
  ProgressBar1.Position:=0;
  handle := Form1.Handle;
  n:=10;
  m:=100;
  SetLength(list,n*m);

  FTask := TTask.create(
    procedure
    var
      processed: integer; // shared counter
      total    : integer; // total number of items to be processed
    begin
      processed := 0;
      total:=n*m;
      TParallel.For(1,total,
        procedure(Index: Integer)
        var
          new: integer;
        begin
          new := TInterlocked.Increment(processed); // increment the shared counter
          if (new mod 10) = 0 then // update the progress bar every 10 processed items
            PostMessage(handle, WM_UPDATE_PROGRESS, Round(new / total * 100), 0);
          //Calculation procedure
          Calc(Index,Total);
        end);
    
      // Update the UI
      TThread.Queue(nil, AfterTest);
    end); // TTask.Run
  FTask.Start;
 

и в AfterTest() процедуре:

 procedure TForm1.AfterTest;
begin
  FTask:=nil;
  ShowMessage('Finished');
end;
 

Когда я запускаю программу, время для завершения выполнения и отображения сообщения «Готово» отличается. Панель прогресса заполняется быстрее. Как мне синхронизировать время между сообщением «Готово» и индикатором выполнения?

Комментарии:

1. Где AfterTest вызывается код get?

2. @R. Хук TThread.Queue(nil, AfterTest);

3. Хамед, используй thread.synchronize вместо Queue .

4. @whosrdaddy хммм, кажется, я пропустил это, переформатируя код … 😊

5. @J… Нет, для задачи есть другой интерфейс, поэтому преждевременного выпуска не будет.

Ответ №1:

Parallel for запускает множество параллельных экземпляров вашего процесса, каждый из которых обновляет ход выполнения, а после этого вызывает Calc() , что означает, что он обновляет ход выполнения перед началом работы. Вот почему прогресс заканчивается задолго до завершения задачи. Сначала вы должны вызвать Calc() .