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
问题解决。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。