Delphi IdTCPClient.连接线程化时挂起

wn9m85ua  于 2022-11-29  发布在  其他
关注(0)|答案(1)|浏览(227)

我正在尝试运行8个线程,使IdTCPClient重复扫描一个IP范围。当这些线程运行时,主窗体挂起,滞后。“IdTCClient.connect”是问题所在。有办法解决吗?

unit Unit3;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TTcpThread = class(TThread)
    Idx: word;
     procedure Execute; override;
  end;

  TForm3 = class(TForm)
    procedure FormShow(Sender: TObject);
  private
  public
  end;
var
  Form3: TForm3;

implementation
uses IdTCPClient;

{$R *.dfm}

procedure TTcpThread.Execute;
begin
  for var i := Idx*8 to (Idx*8) + (8-1) do  // 8 IP per Thread
  begin
    var TCP := TidTCPClient.Create(nil);
    TCP.Host :=  '192.168.1.' + i.ToString;;
    TCP.Port := 9999;
    TCP.ConnectTimeout := 500;
    TCP.ReadTimeout := 1000;
    try
      TCP.Connect;
      TCP.Disconnect;
    except end;
    TCP.Free;
  end;
end;

procedure TForm3.FormShow(Sender: TObject);
begin
  for var i := 0 to 32-1 do  // 32 Threads
  begin
    var Thread := TTcpThread.Create(True);
    Thread.Idx := i;
    Thread.FreeOnTerminate := True;
    Thread.Start;
  end;
end;

end.

线程运行时主窗体将冻结/滞后

anhgbhbe

anhgbhbe1#

解决此问题的一种方法是使用TIDThreadComponent组件。此组件设计用于在线程中运行任务。
使用此组件,您可以为每个IP创建一个线程,然后将IdTCPClient连接代码添加到TIDThreadComponent的OnExecute事件中。这将确保连接代码在单独的线程中运行,因此它不会阻塞主窗体或冻结。
解决此问题的另一种方法是使用异步套接字而不是线程。这种方法允许您建立多个连接,而不必为每个连接创建单独的线程。异步套接字比线程更有效,因此在某些情况下是更好的选择。

相关问题