在此代码中,正如您在Connect上看到的那样,AContext.Data中填充了一些内容
TmyTThreadList = class(TThreadList)
id: integer;
end;
var unique_id:integer;
procedure TfrmTestIdTCPServer.IdTCPServerConnect(AContext: TIdContext);
begin
CS.Enter;
try
inc(unique_id);
finally
CS.Leave;
end;
AContext.Data := myTThreadList.Create;
list := myTThreadList(AContext.Data).LockList;
try
myTThreadList(AContext.Data).id := my_unique_id;
list.Add(myTThreadList(AContext.Data));
finally
myTThreadList(AContext.Data).UnlockList;
end;
end;
然后断开连接,编码器在这里检查Acontext.Data<>零
procedure TfrmTestIdTCPServer.IdTCPServerDisconnect(AContext: TIdContext);
var
begin
if AContext.Data <> nil then
begin
问题是,他为什么要检查nil?
感谢。
修改
我问这个,因为当我这样做时,onExecute我访问AContext.Data,有时(当同时连接多个客户端时)AContext.Data为空,出现访问冲突。
答案 0 :(得分:0)
原始程序员可以出于多种不同的原因检查数据是否为零,真正知道这一点的唯一方法就是问他/她为什么这样做。
我认为可能是:
至于您关心的问题,AFAIK,Indy不会触及Data对象,而是触及Task实例的Destroy序列。
TIdTask.Data文档声明:
用户指定的对象,其中包含在执行任务期间使用的值。 Data是一个TObject属性,表示用户指定的对象实例,其值可以在任务执行期间使用。
在Create中创建任务后,必须将对象实例分配给Data。
Data属性由TIdTask实例拥有,并将在Destroy中释放。
并没有提到任何由Indy本身释放数据的案例。
我做了一个测试,将一个对象分配给一个新连接,在服务器上做一些工作,并从客户端做多个连接,经过几千个连接后,没有人无法保持正确的Data对象附加到每次调用都有AContext,不仅是OnDisconnect,还包括OnExecute事件。
答案 1 :(得分:0)
如果OnConnect
事件处理程序中发生未捕获的异常,则仍可以调用OnDisconnect
事件。如果TThreadList.Create
引发了异常,则不会分配AContext.Data
。