我将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事件中使用Sleep函数时,没有任何变化。 CPU使用率仍为100%。
我的线程优先级为正常。
如何解决我的问题?
答案 0 :(得分: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;
答案 1 :(得分:3)
我不熟悉delphi代码,但是你正在运行一个busy-wait机制,这会磨损你的CPU。
向循环引入睡眠或延迟只会隐藏问题。我建议使用更好的方法来接收您的消息/事件。存在许多解决方案,如观察者 - 侦听器模式或线程等待和通知方案。
<小时/> 一些有用的链接以回应您的评论:
答案 2 :(得分:2)
1我认为你需要一个比9.0.0.18更新的Indy版本。年纪较大的人有明显的线程错误。这包括随Delphi一起提供的所有版本的Indy版本。
2看看有关如何使用Indy的示例代码。
答案 3 :(得分:1)
是否有一个GetMessage版本在消息到达之前等待(阻塞线程)?
答案 4 :(得分:1)
我不知道Get Massage的版本。但它在Windows.pas中声明如此
function GetMessage; external user32 name 'GetMessageA';
答案 5 :(得分:0)
这个项目是一个非常大的项目。所以更新Indy对我来说很难。但如果你确定问题是由于旧版本的Indy,我会更新它。
我看过所有Indy演示。这些演示非常简单。在我的项目中,我的数据传输速度非常快。 (就像实时录音机一样)