0

UI 在我的 OTL 多线程程序执行期间冻结。使用 1 到 16 个线程进行测试,程序启动后 UI 立即冻结。

  Parallel.ForEach(0, CalcList.Count-1)
  .NumTasks(nMax) 
  .NoWait
  .Execute(
   procedure(const value: integer)
   begin
     CalcUnit.EntrySearch(value);
    end)

OmniEventMonitor 正确接收所有线程消息。当所有线程都关闭时,OmniEventMonitor 会立即处理所有接收到的消息。如何确定导致冻结的原因才能找到解决方案。Application.ProcessMessages和/或OmniTED.ProcessMessages 确实OmnitEventMonitorTaskMessage没有影响。

对于 MCVE:在主窗体上:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Parallel.ForEach(0, 1)
  .Execute(
     procedure(const value: integer)
     begin
       CalcUnit.EntrySearch;
     end);
 end;

在 CalcUnit 上

procedure EntrySearch;
var
   I : integer ;
begin
  for I := 1 to 10 do begin
    MessageBeep(MB_ICONEXCLAMATION);
    Sleep(1000) ;
   end;
 end;

MainForm 冻结,直到 CalcUnit 完成。

4

1 回答 1

0

应用程序 UI 冻结,因为它正在等待所有线程都已完成。我不得不在任务完成时销毁 ForEach 接口。使用 MainForm 中的 OnStop 方法销毁最后一个 Thread。看:从 ForEach 循环递增进度条

{Private declarations}
FWorker : IOmniParallelLoop<integer>;

FWorker := Parallel.ForEach(0, CalcList.Count-1)
.TaskConfig(Parallel.TaskConfig.OnMessage(Self))
.NumTasks(nMax) 
.NoWait
.OnStop(procedure (const task: IOmniTask)
  begin
  task.Invoke(procedure begin
      FWorker := nil;
    end);
  end);

FWorker
.Execute(
  procedure (const value: integer)
  begin
     CalcUnit.EntrySearch(value);
  end);
于 2014-11-26T07:53:19.893 回答