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

Delphi中在事件处理器内释放Sender(TCatcherServer实例)是否合规?

Delphi中TCatcherServer实例释放问题解答

这种做法不正确。

原因很直接:当OnFieldsReady事件在TCatcherServer的Callback方法里触发时,TCatcherServer的内部代码大概率还没执行完(比如Callback方法的后续逻辑仍在运行)。这时候直接在事件处理函数里调用Sender.Free释放实例,会导致后续TCatcherServer的代码尝试访问已被释放的内存,轻则触发内存访问错误,重则直接导致程序崩溃。

正确的实现方式主要有以下几种:

  • 延迟释放,避开当前执行流程
    不要在事件处理函数里直接Free,而是把释放操作放到当前调用栈之外执行。比如用TThread.Queue把释放任务放到主线程的消息队列里,等TCatcherServer的Callback方法完全执行完后,再执行释放:

    procedure TMainForm.FieldsReadyHandler(Sender: TObject);
    begin
      // 先获取所需数据
      // ...
      
      // 延迟释放实例
      TThread.Queue(nil, procedure
      begin
        Sender.Free;
      end);
    end;
    

    也可以给窗体发送自定义消息,在窗体的消息处理函数里再执行Sender.Free,效果一致。

  • 让TCatcherServer自行管理销毁
    修改TCatcherServer类的逻辑,在Callback方法触发OnFieldsReady事件之后,确认事件处理完成,再由类内部调用Free。不过这种方式要注意,如果事件处理是异步执行的,得确保实例不会在事件处理完成前被提前销毁。

  • 用引用计数自动管理生命周期
    如果TCatcherServer可以改成继承自TInterfacedObject,那么用接口来持有这个实例,就不用手动调用Free了——当最后一个接口引用被释放时,实例会自动销毁,从根源上避免手动释放的风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 08:12:07