如何正确终止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
相关产品推荐
相关产品推荐

