TThreadList 的LockList问题

项目中使用TThreadList存储客户端的socket连接线程,在有连接时加入到列表,断开时,从列表删除

加入时:

procedure TFrmMain.ServerConnect(AThread: TIdPeerThread);
var
  NewClient: PClient;  
begin
  GetMem(NewClient, SizeOf(TClient));

  NewClient.DNS := AThread.Connection.LocalName;
  NewClient.Connected := Now;
  NewClient.LastAction := NewClient.Connected;
  NewClient.Thread := AThread;

  AThread.Data := TObject(NewClient);
  try
      Clients.LockList.Add(NewClient); 
  finally
      Clients.UnlockList; //需要unlock
  end;
end;
断开时:
procedure TFrmMain.ServerDisconnect(AThread: TIdPeerThread);
var
  ActClient: PClient;
begin
  ActClient := PClient(AThread.Data);
  ChannelManager.Loger.Info('座席[' + ActClient^.DNS + ']断开服务器连接"');
  try
    ChannelManager.UnRegUserChannel(actClient.ChannelID);
    Clients.LockList.Remove(ActClient);
  finally
    Clients.UnlockList;
  end;
  FreeMem(ActClient);
  AThread.Data := nil;
end;
------------------------
后来,加入显示客户数量的语句:
procedure TFrmMain.ServerDisconnect(AThread: TIdPeerThread);
var
  ActClient: PClient;
begin
  ActClient := PClient(AThread.Data);
  ChannelManager.Loger.Info('座席[' + ActClient^.DNS + ']断开服务器连接"');
  try
    ChannelManager.UnRegUserChannel(actClient.ChannelID);
    Clients.LockList.Remove(ActClient);    
  finally
    Clients.UnlockList;
  end;
  FreeMem(ActClient);
  AThread.Data := nil;

  StatusBar1.Panels[3].Text:=format('%d个座席已注册',[Clients.LockList.Count]);
end;
发现:
客户在断开后,重新连接,注册不了。连接是可以的。跟踪代码,发现Server的execute已经不在运行,断开的时候,
发现有exception="connection closed gracefully",此时,count应该为0。后面的显示状态,已经不再执行。

把该句注释掉后,运行正常。
看来:
Locklist是必须要UnLock才行,这是线程安全的List,呵呵。
后,修改为使用一个全局变量保存Clients的个数,Clients初始化时设为0,加入时+1,断开时-1
问题解决。

Del.icio.us :
Flickr :
Technorati :

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据