【问题标题】:How to have a list of IdTCPClients of all my created threads?如何获得我创建的所有线程的 IdTCPClients 列表?
【发布时间】:2012-11-27 14:17:41
【问题描述】:

我创建了一个线程

type 
  ss_thread = class;

  ss_thread = class(TThread)
  protected
    Fff_id : string;
    Fff_cmd : string;
    Fff_host : string;
    Fff_port : TIdPort;
    procedure Execute; override;
  public
    constructor Create(const ff_id, ff_cmd: string; ff_host: string; ff_port: TIdPort);
  end;

constructor ss_thread.Create(const ff_id, ff_cmd: string; ff_host: string; ff_port: TIdPort);
begin
  inherited Create(False);
  Fff_id   := ff_id;
  Fff_cmd  := ff_cmd;
  Fff_host := ff_host;
  Fff_port := ff_port;
end;

...
id := 123; // dynamic
...

nst_ss_thread.Create(id, cmd, host, port);

然后做一些事情

procedure ss_thread.Execute;
var
  ws : TIdTCPClient;
  data : TIdBytes;
  i : integer;
  list : TList;
begin
      ws := TIdTCPClient.Create(nil);
      ws.Host := Fff_host;
      ws.Port := Fff_port;
....

我有主线程,它从其他来源接收数据,我需要将所有数据转发到我的线程,我收到的 ID 是 'ws' IdTCPClient。

如何获得我创建的所有线程的 IdTCPClients 列表?

谢谢

【问题讨论】:

    标签: multithreading delphi thread-safety delphi-xe3


    【解决方案1】:

    将它们存储在线程列表中。

    ClientList: TThreadList<TIdTCPClient>;
    

    在创建任何客户端之前创建这些对象之一。

    ClientList := TThreadList<TIdTCPClient>.Create;
    

    每当您创建客户端时,添加它:

    procedure ss_thread.Execute;
    var
      List: TList<TIdTCPClient>;
    ....
    ws := TIdTCPClient.Create(nil);
    List := ClientList.LockList;
    try
      List.Add(ws);
    finally
      ClientList.UnlockList;
    end;
    

    当您需要迭代客户端时,您可以这样做:

    var
      List: TList<TIdTCPClient>;
      Client: TIdTCPClient;
    ....
    List := ClientList.LockList;
    try
      for Client in List do
        // do something with Client
    finally
      ClientList.UnlockList;
    end;
    

    在线程的析构函数中,您还需要从列表中删除客户端。

    【讨论】:

    • 我也正要建议:) 在列表中添加/删除 TIdTCPClients 以及发送时请注意异常 - 由于套接字的异步状态,在某些阶段几乎是不可避免的。
    • 在线程的析构函数中(在inherited 调用之前)找到它并从ClientList 中删除。
    • 您可以通过某些方式减少异常,例如。通过强制所有线程通过受 CS 保护的状态机访问套接字/列表,但我不确定这是否值得..
    • @TLama - 是的,但这可能为时已晚,无法阻止发送线程尝试写入死套接字并因此无论如何都会产生异常:(
    • @TLama:我将覆盖线程的DoTerminate() 方法,而不是使用析构函数,从列表中删除TIdTCPClient,并释放TIdTCPClient
    猜你喜欢
    • 2011-01-04
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    • 2019-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多