Delphi OTL多线程UI冻结

时间:2014-11-22 20:56:40

标签: multithreading delphi omnithreadlibrary

在执行我的OTL多线程程序期间,UI冻结。 使用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.ProcessMessagesOmnitEventMonitorTaskMessage确实没有影响力。

对于MCVE: 在mainform上:

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完成。

1 个答案:

答案 0 :(得分:0)

应用程序UI冻结,因为它正在等待所有线程都已完成。我必须在任务完成时销毁ForEach接口。使用MainForm中的OnStop方法来销毁最后一个Thread。请看:Incrementing Progress Bar from a ForEach Loop

{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);