【发布时间】:2014-11-22 20:56:39
【问题描述】:
在我的 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: 在主窗体上:
procedure TForm1.Button1Click(Sender: TObject);
begin
Parallel.ForEach(0, 1)
.Execute(
procedure(const value: integer)
begin
CalcUnit.EntrySearch;
end);
end;
在计算单元上
procedure EntrySearch;
var
I : integer ;
begin
for I := 1 to 10 do begin
MessageBeep(MB_ICONEXCLAMATION);
Sleep(1000) ;
end;
end;
MainForm 冻结,直到 CalcUnit 完成。
【问题讨论】:
-
你为什么要打电话给
ProcessMessages?我们可以有一个 MCVE 吗? -
@DavidHeffernan 感谢您的快速回复。希望用 ProcessMessages 解冻主线程,(没用)
-
“解冻的希望”有时被称为“意外编程”。了解
ProcessMessages在使用时的作用很重要。它的滥用可能导致微妙问题的噩梦。 .... 至于为什么你的 UI 卡住了?这将是由于CalcUnit.EntrySearch方法内部的某些东西(或它调用的东西等)。 -
为了解决问题,您必须首先诊断并理解它。这将需要某种调试。我们不能在没有代码的情况下做到这一点。您需要显示代码、MCVE,或者自己进行调试。
-
@CraigYoung 感谢您的 cmets,英语不是我的母语。我知道 ProcessMessages 做了什么,从 Delphi 4 开始就一直在使用 Delphi。虽然是多线程的新手。我用来处理消息的 ProcessMessages,通过 OmniEventMonitor,从线程设置进度条,(没有工作)。在线程内部,我确实删除了与 MainForm 的所有连接,但没有解决冻结问题。
标签: multithreading delphi omnithreadlibrary