AContext.data可以是nil吗?

时间:2012-11-26 03:09:23

标签: delphi indy delphi-xe3

在此代码中,正如您在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为空,出现访问冲突。

2 个答案:

答案 0 :(得分:0)

原始程序员可以出于多种不同的原因检查数据是否为零,真正知道这一点的唯一方法就是问他/她为什么这样做。

我认为可能是:

  • 即使在任何连接上创建了新的 Data 对象,也可以在连接的生命周期内释放此对象 ,其他任何数量或原因。例如,在该服务器组件的OnExecute事件处理程序中,由于存储在那里的数据或来自客户端或其他外部源的请求。
  • 也许在连接的生命周期中要执行的代码超出原始程序员控件,因此他/她没有其他方法可以知道Data对象是否仍在那里,例如组件编写者应该进行这种测试,或者在团队中工作的库程序员。
  • 原始编码器就是那种防御性程序员并且正在应用检查,即使他/她知道Data对象应该在那里,但只是为了确保它是并且阻止意外访问违规。

至于您关心的问题,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