Indy的问题(100分)

  • 主题发起人 主题发起人 CODEHUNTER
  • 开始时间 开始时间
C

CODEHUNTER

Unregistered / Unconfirmed
GUEST, unregistred user!
TIdTCPServer,在用ReadBuffer()函数时,如果读不到预期的字节数,并且处于阻塞
等待状态,这时候客户端关闭程序,于是服务端就当掉了,这时cpu利用率达到99%

如何解决?
 
好像记得Indy采用的是阻塞方式 我觉得取数据这一过程最好
用单独的一个线程来做 这样出现这种情况的话可以摧毁改线线程即可
 
你说的对用线程,我就是用线程的,我只是对最后的99%cpu占用率表示疑惑

是否是indy的bug,正在进一步论证
 
单独开个线程:你要自己改一下咯
unit u_SocketChecker;

interface

uses
Classes, syncobjs, Windows, sysutils;

type
TSocketChecker = class(TThread)
private
{ Private declarations }
FCrit: TCriticalSection;
ThreadList: TList;
public
FShutDownEvent: TEvent;
public
constructor Create(CreateSuspend: Boolean);
destructor Destroy; override;
procedure Execute; override;
procedure AddThread(TT: TObject);
procedure RemoveThread(TT: TObject);
end;

implementation
uses u_ClientSocketThreadRoot, U_Logger;

{ TSocketChecker }

procedure TSocketChecker.AddThread(TT: TObject);
begin
FCrit.Enter;
ThreadList.Add(TT);
FCrit.Leave;
end;

constructor TSocketChecker.Create(CreateSuspend: Boolean);
begin
inherited Create(true);
FCrit := TCriticalSection.Create;
ThreadList := TList.Create;
FreeOnTerminate := true;
if not CreateSuspend then
resume;
end;

destructor TSocketChecker.Destroy;
begin
ThreadLIst.free;
ThreadLIst := nil;
FCrit.Free;
FCrit := nil;
inherited;
end;

procedure TSocketChecker.Execute;
var
TT: TClientSocketThreadRoot;
i: Integer;
CurrentTick: Integer;
TimeOutValue: Integer;
begin
{ Place thread code here }
while (not Terminated) and (FShutDownEvent.WaitFor(1000) = wrTimeout) do
begin
for i := 0 to ThreadList.Count - 1 do
begin
try
TT := TClientSocketThreadRoot(ThreadList.Items);
if TT.Socket.Connected then
begin
CurrentTick := GetTickCount;
try
TimeOutValue := StrToInt(TT.RunParams.Values['网络超时']);
except
TimeOutValue := 10000;
end;
if (CurrentTick - TT.FLastReadTimeStamp > TimeOutValue) or
(CurrentTick - TT.FLastWriteTimeStamp > TimeOutValue) then
begin
TT.Socket.Disconnect;
TT.FLastWriteTimeStamp := CurrentTick;
TT.FLastReadTimeStamp := CurrentTick;
LogIt('任务:<%s>网络超时,断开', [TT.RunParams.Values['任务名称']]);
end;
end;
except
break;
end;
end;
end;
end;

procedure TSocketChecker.RemoveThread(TT: TObject);
begin
FCrit.Enter;
ThreadList.Delete(ThreadList.IndexOf(TT));
FCrit.Leave;
end;

end.

 
多人接受答案了。
 
后退
顶部