Цикл сообщения потока зависает в Delphi

У меня есть простая программа Delphi, что я продолжаю работать, в котором я пытаюсь использовать поточную обработку, чтобы разделить функциональность программы от ее GUI и сохранить GUI быстро реагирующим во время более долгих задач, и т.д. В основном у меня есть 'контроллер' TThread и 'представление' TForm. Представление знает дескриптор контроллера, который оно использует для отправки сообщений контроллера через PostThreadMessage. У меня не было проблемы в прошлом использовании этого вида модели для форм, которые не являются основной формой, но по некоторым причинам, когда я пытаюсь использовать эту модель для основной формы, цикл сообщения потока просто выходит.

Вот мой код для цикла сообщения потоков:

procedure TController.Execute;
var
  Msg : TMsg;
begin
  while not Terminated do begin
    if (Integer(GetMessage(Msg, hwnd(0), 0, 0)) = -1) then begin
      Synchronize(Terminate);
    end;

    TranslateMessage(Msg);
    DispatchMessage(Msg);

    case Msg.message of
      // ...call different methods based on message
    end;
  end;
end;

Для установки контроллера я делаю это:

Controller := TController.Create(true); // Create suspended
Controller.FreeOnTerminate := True;
Controller.Resume;

Для обработки сообщений основной формы я попытался использовать обоих Application.Run и следующий цикл (сразу после Controller.Resume)

while not Application.Terminated do begin
  Application.ProcessMessages;
end;

Я работал застрявший сюда - любая справка значительно ценилась бы.

5
задан Erik Westenbroek 22 March 2010 в 21:19
поделиться

2 ответа

Я тестировал ваш код как есть, и он работал нормально. Попробуйте добавить вызов GetLastError после того, как GetMessage вернет -1, чтобы узнать, в чем проблема.

Из кода не совсем понятно, создаете ли вы окна в потоке контроллера, но если нет, я бы предложил передать -1 вместо 0 в качестве HWND для GetMessage и удалить вызовы TranslateMessage / DispatchMessage, поскольку оператор case, который следует за ними, должен обрабатывать все получаемые вами сообщения.

Кроме того, вам не нужно выполнять команду «Синхронизировать (завершить)» в случае ошибки. Terminate просто устанавливает для логического «Terminated» значение true, поэтому вам не нужно его синхронизировать, и вы можете так же легко использовать «Break» для выхода из цикла с тем же эффектом.

3
ответ дан 15 December 2019 в 06:22
поделиться

Где "конец" для цикла while? Я думаю, что вам не хватает конца. Так что, возможно (в зависимости от фактического кода), вы застряли в while not Terminated do бесконечном цикле на одном операторе.

0
ответ дан 15 December 2019 в 06:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: