6

我将 Indy 9 与 Delphi 5 一起使用。在我的应用程序中,我想通过 UDP 与网络设备通信。所以我使用UDPServer comp。在从 TThread 派生的类中。当我编写类似于以下代码时,CPU 使用率为 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;

当我在 while-do 循环或 OnUDPRead 事件中使用睡眠功能时,没有任何变化。CPU使用率仍然是100%。

我的线程优先级是正常的。

我该如何解决我的问题?

4

6 回答 6

6

您遇到的问题是因为您在 GUI 线程中接收 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;
于 2009-02-04T09:25:06.523 回答
3

我对 delphi 代码并不熟悉,但你正在运行一个繁忙的等待机制,它正在磨削你的 CPU。

在循环中引入睡眠或延迟只会隐藏问题。我建议使用更好的方法来接收您的消息/事件。存在许多解决方案,例如观察者-侦听器模式,或线程等待和通知方案。


针对您的评论的一些有用链接:

于 2009-02-04T08:57:46.267 回答
2

1 我认为您需要比 9.0.0.18 更新的 Indy 版本。较旧的有显示停止线程错误。这包括与 Delphi 一起交付的所有版本的 Indy,直到版本 7。

2 查看有关如何使用 Indy 的示例代码。

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

于 2009-02-04T09:13:00.400 回答
1

是否存在等待(阻塞线程)直到消息到达的 GetMessage 版本?

于 2009-02-04T09:01:00.673 回答
1

我不知道 GetMassage 的版本。但它像这样在 Windows.pas 中声明

function GetMessage; external user32 name 'GetMessageA';
于 2009-02-04T09:11:11.370 回答
0

这个项目是一个非常大的项目。所以更新 Indy 对我来说很困难。但是如果你确定问题是因为旧版本的 Indy,我会更新它。

我看过所有的 Indy 演示。这些演示非常简单。在我的项目中,我的数据传输速度非常快。(像实时录音机)

于 2009-02-04T09:22:47.043 回答