为什么一旦调用 Button2Click(即IDTcpServer.Threads.LockList.Count)后,在ISTCPSERVER中的线程就无法继续工作?
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdTCPConnection, IdTCPClient, IdBaseComponent, IdComponent,
  IdTCPServer, StdCtrls, ComCtrls;type
  TForm1 = class(TForm)
    List: TListView;
    List2: TListView;
    Button1: TButton;
    IDTCPServer: TIdTCPServer;
    IdTCPClient1: TIdTCPClient;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure IDTCPServerConnect(AThread: TIdPeerThread);
    procedure IDTCPServerExecute(AThread: TIdPeerThread);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
  IdTCPClient: TIdTCPClient;
begin
try
    IdTCPClient:=TIdTCPClient.Create(self);
    IdTCPClient.Port:=2222;
    IdTCPClient.Host:='127.0.0.1';
    IdTCPClient.Connect(5000);
except
    IdTCPClient.Disconnect;
    IdTCPClient.Free;
end;end;procedure TForm1.Button2Click(Sender: TObject);
var
  Item:TListItem;
  I:integer;
begin
try
  List2.Clear;
  for i:=0 to IDTcpServer.Threads.LockList.Count-1 do
  begin
    item:=List2.Items.Add;
    item.Caption:=TIdPeerThread(IDTcpServer.Threads.LockList.Items[i]).Connection.Socket.Binding.PeerIP;
  end;
finally
  IDTCPServer.Threads.UnlockList;//已经解锁了啊.
end;
end;procedure TForm1.IDTCPServerConnect(AThread: TIdPeerThread);
var
  Item:TListItem;
begin  item:=List.Items.Add;
  item.Caption:=athread.Connection.Socket.Binding.PeerIP;
  Athread.Suspend;//一旦调用IDTcpServer.Threads.LockList.Count后,LIST中就不会显示ATHREAD的信息?
end;
procedure TForm1.IDTCPServerExecute(AThread: TIdPeerThread);
begin
//dd
end;end.

解决方案 »

  1.   

    请问为什么要用:Athread.Suspend; 这个语句?线程挂起了就不自动操作了(这个线程用于守护对应客户端的消息的,所以正常时要运行的),问题可能就出在这里。
    还有建议用一个局部 TList 变量存放 IDTcpServer.Threads.LockList,这样可以避免对 IDTcpServer.Threads 进行多次 Lock 操作(会出现什么问题还没有找到参考,但是不建议这么做)。
    希望有所帮助。
      

  2.   

    Athread.Suspend是我不用这个线程的时候就让他休眠,要使用的时候就激活他,这个应该没有什么影响吧.
    我按您说的修改了代码还是不行:procedure TForm1.Button1Click(Sender: TObject);
    var
      IdTCPClient: TIdTCPClient;
    begin
    try
        IdTCPClient:=TIdTCPClient.Create(self);
        IdTCPClient.Port:=2222;
        IdTCPClient.Host:='127.0.0.1';
        IdTCPClient.Connect(5000);
    except
        IdTCPClient.Disconnect;
        IdTCPClient.Free;
    end;end;procedure TForm1.Button2Click(Sender: TObject);
    var
      Item:TListItem;
      I:integer;
      Ls:TList;
    begin
    try
      List2.Clear;
      ls:=Tlist.Create;
      ls:= IdThreadMgrDefault1.ActiveThreads.LockList;
      for i:=0 to ls.Count-1 do
      begin
        item:=List2.Items.Add;
        item.Caption:=TIdPeerThread(ls.Items[i]).Connection.Socket.Binding.PeerIP;
      end;
    finally
      IdThreadMgrDefault1.ActiveThreads.UnlockList;
      Ls.Free;
    end;
    end;procedure TForm1.IDTCPServerExecute(AThread: TIdPeerThread);
    var
      Item:TListItem;
    begin  item:=List.Items.Add;
      item.Caption:=athread.Connection.Socket.Binding.PeerIP;
      Athread.Suspend;
    end;end.
      

  3.   

    我用的是INDY9_00_14+delphi7+winxop
      

  4.   

    但是你两次程序里都是无条件的执行 Athread.Suspend; 我还是不解。
    你上例有问题,不必用 ls:=Tlist.Create; 这句,因为 IdThreadMgrDefault1.ActiveThreads.LockList 本身就返回了一个 TList 对象的参考(指针),所以也就不能进行 Ls.Free;。
    TIdThreadMgrDefault 没有用过,不知在这里例子中有没有影响。
      

  5.   

    Athread.Suspend不是没有条件的.我的程序中是检测一个TSTRINGLIST是否存在字符串,即检查是否要发送数据,
    源程序是这样的,不过Athread.Suspend应该没有影响吧.
    //////////////////////////////////////////////////
      item:=List.Items.Add;
      item.Caption:=athread.Connection.Socket.Binding.PeerIP;
    if Stringlist.count<1 then 
      Athread.Suspend
    else 
      DO SOMETING
    ////////////////////////////////////////////////////