2014-11-22 85 views
0

在執行我的OTL多線程程序期間UI凍結。 使用1到16個線程進行測試,UI在程序啓動後立即凍結。Delphi OTL多線程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

你爲什麼要調用'ProcessMessages'?我們可以有一個MCVE? – 2014-11-22 20:57:55

+0

@DavidHeffernan感謝您的快速回復。希望通過ProcessMessages解凍主線程,(不起作用) – 2014-11-22 21:28:57

+1

「希望解凍」有時被稱爲「偶然編程」。瞭解'ProcessMessages'在您使用時會做些什麼很重要。它的濫用可能導致一些微妙問題的噩夢。 ....至於你的UI爲什麼會凍結?這將歸因於'CalcUnit.EntrySearch'方法內部的東西(或者它調用的東西等)。 – 2014-11-22 21:45:38

回答

0

應用程序UI凍結,因爲它正在等待所有線程已完成。我必須在任務完成時銷燬ForEach界面。在MainForm中使用OnStop方法銷燬最後一個線程。看看: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);