Indy10 file transfer causes 100% CPU usage

I managed to fix some errors with shutdown, now whenever the file transfers, the CPU usage becomes 100%, I don’t know what I am doing wrong: S .....

const
 MaxBufferSize = 1024;

type
 TClient = class(TObject)
 public
  AContext: TIdContext;
  FileSize: Integer;
  Canceled: Boolean;
  Transfered: Integer;
  procedure ReceiveData;
  procedure Update;
 end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
 Data: string;
 Client: TClient;
 Item: TListItem;
begin
 Data := AContext.Connection.IOHandler.ReadLn;

 //Data := 'SEND|785548' = Command + | + FileSize
 if Copy(Data, 1, 4) = 'SEND' then
 begin
  Delete(Data, 1, 5);
  Client := TClient.Create;
  Client.FileSize := StrToInt(Data);
  Client.AContext := AContext;
  Item := ListView1.Items.Add;
  Item.Caption := AContext.Connection.Socket.Binding.PeerIP;
  Item.Data := Client;
  Client.ReceiveData;
 end;
end;

procedure TClient.ReceiveData;
var
 currRead : Integer;
 FS: TFileStream;
begin
 Canceled := False;
 FS := TFileStream.Create('C:\Test.dat', fmCreate or fmOpenReadWrite);
 FS.Size := 0;
 Transfered := 0;
 try
  while (FS.Position < FileSize) and (Athread.Connection.Connected) and (not Canceled) do
  begin
   Application.ProcessMessages;
   if (FileSize - FS.Position) >= MaxBufferSize then currRead := MaxBufferSize
   else currRead := (FileSize - FS.Position);
   AThread.Connection.IOHandler.ReadStream(FS, CurrRead);
   Transfered := FS.Position;
   Notify.NotifyMethod(Update);
   Application.ProcessMessages;
  end;
 finally
  FS.Free;
  AThread.Connection.IOHandler.InputBuffer.Clear;
  AThread.Connection.Disconnect;
  AThread.RemoveFromList;
  Notify.NotifyMethod(Update);
  Application.ProcessMessages;
 end;
end;

procedure TClient.Update;
begin
 //Code to Display Progress bar and stuff (Simplified for now)
 Form1.Label1.Caption := 'Transfered Data : ' + IntToStr(Transfered);
end;
+3
source share
5 answers

Get rid of Application.ProcessMessages; it MUST NOT be called in a thread other than the main one.

+6
source

You call Application.ProcessMessages in your receive loop, presumably to make the rest of your application look frozen. Using 100% of the processor is a side effect.

IdAntiFreeze ( ) ReceiveData .

Update:

. , , , , IdTcpServer. APZ28 ; Application.ProcessMessages .

+4

Indy ( , / Indy, / TCP/IP - . http://synopse.info), , IdTCPServer1Execute , .

:

  • Application.ProcessMessages ..
  • ( , ), Notify() Synchronize();
  • , IdTCPServer1 ( - );
  • ( ) , ReadStream ; , , Indy .
  • ( - http://delphitools.info), , .
  • IDE - ?
+2

Your loop constantly, easy hacking - add Sleep(1)after Application.ProcessMessages.

But perhaps you can reorder your code to block the ReadStream function and run it only when a reasonable amount of data is received or a timeout is missed.

+1
source

You and I covered this topic in the Embarcadero Forums section ( cached by CodeNewsFast ).

+1
source

Source: https://habr.com/ru/post/1774781/


All Articles