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

如何正确终止TNetHTTPClient针对直播流的Get请求?

问题描述

我用线程结合TNetHTTPClient组件从摄像头直播流获取数据。这个摄像头只有检测到运动时才会拍摄图像,所以流不是连续的。HTTPClient调用Get方法传入内存流MSImage,OnReceiveData事件处理器负责处理流数据并提取图像,这部分功能正常。但不确定应用关闭时如何终止Get请求,试过同步和异步模式,当前用异步模式,通过repeat-until循环让Execute方法运行到线程终止。把OnReceiveData事件的AAbort参数设为True时应用能正常关闭,但因为流数据不连续,没法保证关闭时该事件会触发。当前代码能运行,但应用关闭时会出现内存泄漏,泄漏的是关闭时内存流中的数据。请问正确终止Get请求的方法是什么?

procedure TReadThread.Execute;
var
  HTTPClient: TNetHTTPClient;
begin
  inherited;
  HTTPClient := TNetHTTPClient.Create(nil);
  HTTPClient.Asynchronous := True;
  HTTPClient.OnReceiveData := HTTPClientReceiveData;

  try
    HTTPClient.PreemptiveAuthentication := True;
    HTTPClient.CredentialsStorage.AddCredential(TCredentialsStorage.TCredential.Create(TAuthTargetType.Server, '', FEndpoint, 'username', 'password'));
    HTTPClient.Get(FEndpoint, MSImage);

    repeat
      FTerminateEvent.WaitFor(100);
    until Terminated;

  finally
    MSImage.Clear;
    HTTPClient.Free;
  end;
end;
解决方案

要正确终止异步Get请求并避免内存泄漏,可按以下方式调整代码:

  • 主动取消HTTP请求:线程终止时调用HTTPClient.CancelAll,该方法会立即终止所有正在进行的异步请求,无需依赖OnReceiveData事件触发。
  • 优化线程循环逻辑:循环中同时监听终止信号和请求状态,避免无效等待。
  • 安全清理资源:确保取消请求后内存流被彻底清理,释放HTTPClient前确认所有异步操作已终止。

修改后的Execute方法示例:

procedure TReadThread.Execute;
var
  HTTPClient: TNetHTTPClient;
begin
  inherited;
  HTTPClient := TNetHTTPClient.Create(nil);
  try
    HTTPClient.Asynchronous := True;
    HTTPClient.OnReceiveData := HTTPClientReceiveData;
    HTTPClient.PreemptiveAuthentication := True;
    HTTPClient.CredentialsStorage.AddCredential(TCredentialsStorage.TCredential.Create(TAuthTargetType.Server, '', FEndpoint, 'username', 'password'));

    // 启动异步Get请求
    HTTPClient.Get(FEndpoint, MSImage);

    repeat
      // 等待终止信号或请求完成
      if FTerminateEvent.WaitFor(100) = wrSignaled then
      begin
        // 线程终止,取消所有HTTP请求
        HTTPClient.CancelAll;
        Break;
      end;
      // 检查请求是否已完成(可选,根据场景调整)
      if not HTTPClient.IsBusy then
        Break;
    until Terminated;

  finally
    // 彻底清理内存流数据
    MSImage.Clear;
    // 释放组件前确保异步任务已终止
    HTTPClient.Free;
  end;
end;

额外注意:主线程触发线程终止时,需先调用TReadThread.Terminate,再调用WaitFor等待线程完全结束,不要强制终止线程,确保线程内的清理逻辑正常执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:57:13