在执行我的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.ProcessMessages
在OmnitEventMonitorTaskMessage
确实没有影响力。
对于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完成。
答案 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);