2014-11-22 3 views
0

Пользовательский интерфейс зависает во время выполнения моей многопоточной программы OTL. Протестировано с резьбой от одного до 16, пользовательский интерфейс замерзает сразу после начала процедуры.Delphi OTL Многопользовательский интерфейс замораживается

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 не будет завершена.

+1

Зачем вам называть 'ProcessMessages'? Можем ли мы иметь MCVE? –

+0

@DavidHeffernan Спасибо за ваш быстрый ответ. Надежно разморозить mainthread с помощью ProcessMessages (не работает) –

+1

«Надежда разморозить» иногда называют «программированием случайно». Важно понимать, что делает 'ProcessMessages', когда вы его используете. Это неправильное использование может привести к кошмару тонких проблем. ... Что касается того, почему ваш пользовательский интерфейс замерзает? Это будет связано с чем-то внутри метода CalcUnit.EntrySearch (или что-то, что он вызывает и т. Д.). –

ответ

0

Пользовательский интерфейс приложения зависает, потому что он ждет завершения всех потоков. Мне пришлось уничтожить интерфейс ForEach при завершении задачи. Используется метод OnStop в MainForm для уничтожения последнего потока. Посмотрите: 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); 
Смежные вопросы