You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi7转10.2 Tokyo:Indy9 TIdPeerThread.ReturnValue替换方案求助

适配Indy 10的代码改造方案

老哥,我刚好处理过类似的Delphi版本迁移+Indy升级的活儿,5万多行代码确实头大,不过你这段断开连接的代码适配Indy10其实没那么复杂,我给你拆解一下:

首先得明确Indy 9到10的几个核心变化,你这段代码里直接涉及的点:

  • Indy9的TIdPeerThread在Indy10里被替换成了TIdContext,所有客户端连接的上下文信息都存在这个类里
  • TIdPeerThread.ReturnValue这个属性在Indy10里被移除了,需要我们自定义上下文类来存储这个标识值
  • Indy10的线程生命周期由框架自动管理,不需要手动调用Terminate(特殊场景除外)

第一步:自定义上下文类

先创建一个继承自TIdServerContext的类,用来存储原来ReturnValue对应的标识:

type
  TMyServerContext = class(TIdServerContext)
  public
    CtrlTrnsID: Integer; // 对应原来的AThread.ReturnValue
    constructor Create(AConnection: TIdTCPConnection; AYarn: TIdYarn; AList: TIdContextThreadList); override;
  end;

constructor TMyServerContext.Create(AConnection: TIdTCPConnection; AYarn: TIdYarn; AList: TIdContextThreadList);
begin
  inherited;
  CtrlTrnsID := 0; // 初始化,后续在连接建立时赋值(对应原来给ReturnValue赋值的逻辑)
end;

然后在你的TIdTCPServer的OnCreateContext事件里返回这个自定义类的实例:

procedure TTraceForm.IdTCPServer1CreateContext(AConnection: TIdTCPConnection; AYarn: TIdYarn; AList: TIdContextThreadList; var AContext: TIdContext);
begin
  AContext := TMyServerContext.Create(AConnection, AYarn, AList);
end;

第二步:改造Disconnect事件代码

现在把原来的OnDisconnect事件代码改成适配Indy10的版本:

procedure TTraceForm.IdTCPServer1Disconnect(AContext: TIdContext);
var
  MyContext: TMyServerContext;
begin
  try
    // Indy10里框架会自动处理线程终止,不需要手动调用Terminate
    // 如果确实需要强制终止连接,可使用以下代码(一般无需额外操作)
    // AContext.Connection.IOHandler.Close;

    MyContext := AContext as TMyServerContext;
    if (MyContext.CtrlTrnsID >= 1) and (MyContext.CtrlTrnsID <= MaxCtrlTrns) then
    begin
      QueueBlock.Enter;
      try
        TCPPeerThreads[MyContext.CtrlTrnsID] := nil;
      finally
        QueueBlock.Leave;
      end;
    end;
  except
    on E: Exception do
    begin
      WriteLogSwitch('E', 'Error in TTraceForm.IdTCPServer1Disconnect: ' + E.Message);
    end;
  end;
end;

关键注意点

  • 原来给AThread.ReturnValue赋值的地方,现在要改成给TMyServerContext.CtrlTrnsID赋值,比如在OnConnect或业务代码里找到对应逻辑,替换成(AContext as TMyServerContext).CtrlTrnsID := XXX;
  • 如果TCPPeerThreads数组原来存储的是TIdPeerThread实例,现在要根据业务逻辑调整为存储TIdContext或TMyServerContext(如果只是标记连接状态,保持赋值nil的逻辑即可)
  • 5万多行代码的迁移,Unicode适配也是重头戏,建议同步把AnsiString替换为String,同时检查所有字符串相关的API(文件、网络、UI),避免出现乱码问题

内容的提问来源于stack exchange,提问作者alejobog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:08:46