簡體   English   中英

如何在並行線程中顯示進度

[英]How to show progress in the parallel threads

我有一個這樣的代碼:

procedure TSeries.Read;
var
 ReadProc: TParallelFunction2;
 Counter:  integer;
begin
 try
  ProgressForm.Show;
  Counter  := 0;
  ReadProc :=
   procedure (i1, i2, tdi: integer)
   var
    i: integer;
   begin
    for i := i1 to i2 do
     if not FDASlice[i].PctPresent then
     begin
      TInterlocked.Increment(Counter);
      ReadSlice(i, True);
     end;
   end;

  Parallel.ForI(0, High, ReadProc, pfDivide);
 finally
  ProgressForm.HideForm;
 end;
end;

它使用 STParallel 庫在多線程模式下處理 ReadProc 過程。 一切正常,但我需要向用戶顯示進度。 我嘗試將 'Application.ProcessMessage' + 'ProgressForm.SpTBXProgressBar1.Position := Counter' 添加到 ReadProc 或 'TThread.Synchronize' 中,但沒有成功。 應用程序掛起,不顯示進度。

我怎樣才能顯示進度? 是否有可能在該代碼中,或者需要將所有非主線程移動到其他地方? 謝謝你。

解決這個問題的最簡單也是最好的方法是讓主線程更新計時器的進度。

您需要授予計時器事件訪問進度計數器的權限。 這意味着將Counter變量從局部變量轉換為 UI 可以訪問的類的變量。 您不需要同步對計數器的訪問,因為 UI 沒有修改它,並且您已經使用原子增量函數來修改計數器。

所以,你需要的步驟是:

  1. Counter變量移動為一個類的成員,UI 可以訪問該類。
  2. 以適當的更新頻率向 UI 添加計時器。 100 毫秒的計時器間隔將綽綽有余。
  3. 在計時器事件中,將進度條的位置設置為計數器的瞬時值。

那么為什么這種方法比你的好? 好吧,進程 UI 更新不應該由工作線程驅動。 這樣做可能會因刷新而使 UI 不堪重負。 這會嚴重阻礙性能和可擴展性。

而是讓工作人員更新進度狀態,但讓 UI 負責驅動更新。 UI 知道刷新太頻繁沒有意義,只有它可以確定刷新率。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM