Frits Molenkamp
Frits Molenkamp

Reputation: 175

Delphi OTL Multithreading UI freezes

The UI freezes during execution of my OTL multithreaded program. Tested with one to 16 thread, UI freezes immediately after procedure start.

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

All thread messages are correctly received by the OmniEventMonitor. When all threads are closed the OmniEventMonitor handles all the received messages at once. How can I determine what causes the freezing to find a resolution. Application.ProcessMessages and/or OmniTED.ProcessMessages in the OmnitEventMonitorTaskMessage does have no influence.

for a MCVE: on mainform:

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

on the CalcUnit

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

the MainForm freezes until the CalcUnit is completed.

Upvotes: 0

Views: 764

Answers (1)

Frits Molenkamp
Frits Molenkamp

Reputation: 175

The Application UI freezes because it is waiting for all threads have been completed. I had to destroy the ForEach interface at task Completion. Used the OnStop method in the MainForm to destroy the last Thread. Look at: 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);

Upvotes: 0

Related Questions