100% загрузка процессора в Delphi - PullRequest
5 голосов
/ 04 февраля 2009

Я использую Indy 9 с Delphi 5. В моем приложении я хочу общаться с сетевым устройством через UDP. Поэтому я использую UDPServer Comp. в классе, который является производным от TThread. Когда я пишу аналогично следующему коду, загрузка процессора составляет 100%.

в теме:

while not terminated do begin
  if GetMessage(Msg, 0, 0, 0) then begin
    if Msg.message = WM_UDPMSG then
      Break
    else
      DispatchMessage(Msg);
  end;
end;

и событие OnUDPRead:

  try    
    // Processing the data here
  except
    PostThreadMessage(ThreadId, WM_UDPMSG, 0, 0);
  end;

Когда я использую функцию Sleep в цикле while-do или в событии OnUDPRead, никаких изменений не происходит. Тем не менее загрузка процессора составляет 100%.

Приоритет моей темы - Нормальный.

Как мне решить мою проблему?

Ответы [ 6 ]

6 голосов
/ 04 февраля 2009

Проблема в том, что вы получаете данные UDP в потоке графического интерфейса, но хотите обработать данные в другом потоке.

Настоящая проблема в том, что вы пытаетесь использовать асинхронный компонент блокирующим образом. Лучшее решение - использовать реальную блокирующую коммуникационную библиотеку UDP, такую ​​как synapse . Тогда очень просто дождаться получения новых данных в вашей ветке.

Вы могли бы просто написать:

while not Terminated do
begin
  BytesRead := FSocker.RecvBufferEx(@(Buffer[0]), BufferSize, Timeout);
  if (BytesRead = 0) then
  begin
    // continue or exit if the receiving Failed
    case FSocket.LastError of
      0, WSAETIMEDOUT: Continue;
      WSAECONNRESET, WSAENETRESET,
        WSAENOTCONN, WSAECONNABORTED,
        WSAENETDOWN:
        begin
          CloseConnection;
          Exit;
        end;
    else
      CloseConnection;
      Exit;
    end;    
  end;
  // process the data in the buffer
end;
3 голосов
/ 04 февраля 2009

Я не знаком с Delphi-кодом, но вы используете механизм busy-wait , который измельчает ваш процессор.

Введение в спящий режим или задержки в петле только скрывает проблему. Я предлагаю использовать лучший метод для получения ваших сообщений / событий. Существует много решений, например, шаблон наблюдателя-слушателя или схемы ожидания и уведомления потока.


Несколько полезных ссылок в ответ на ваш комментарий:
2 голосов
/ 04 февраля 2009

1 Вам нужна версия Indy новее, чем 9.0.0.18, я думаю. У более старых из них есть жуткие ошибки. Это включает в себя все версии Indy, поставляемые с Delphi до версии 7.

2 Посмотрите пример кода о том, как работать с Indy.

http://www.indyproject.org/demos/index.html

1 голос
/ 04 февраля 2009

Я не знаю версию GetMassage. Но в Windows.pas объявлено так:

function GetMessage; external user32 name 'GetMessageA';
1 голос
/ 04 февраля 2009

Существует ли версия GetMessage, которая ожидает (блокирует поток), пока не прибудет сообщение?

0 голосов
/ 04 февраля 2009

Этот проект очень большой. Поэтому обновление Indy для меня сложно. Но если вы уверены, что проблема из-за старой версии Indy, я обновлю ее.

Я посмотрел все демо Indy. Эти демонстрации очень просты. В моем проекте у меня очень быстрая передача данных. (Как звукозапись в реальном времени)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...