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

如何使用异步TNetHTTPClient?运行测试代码报错该如何解决?

报错原因
  • 开启Asynchronous := True异步模式后,Get方法会立即返回,不会等待网络请求执行完成,此时你拿到的IHTTPResponse对象还处于未就绪状态,直接访问ContentAsString属性就会触发句柄状态异常
  • 你将TNetHTTPClient声明为局部变量,Get调用后立刻在finally代码块中释放了实例,后台还在执行的异步请求失去了关联的宿主实例,也会导致状态错误
解决方法

分两种场景适配:

场景1:不需要异步逻辑,直接使用同步模式

把Asynchronous属性设为False即可,Get方法会阻塞直到请求完成后再返回,此时可以正常访问响应内容,代码示例:

procedure TForm1.Button1Click(Sender: TObject);
var
  httpclient: TNetHTTPClient;
  output: string;
begin
  httpclient := TNetHTTPClient.Create(nil);
  try
    httpclient.Asynchronous := False;
    output := httpclient.Get('https://google.com').ContentAsString;
    // 此处可正常处理返回结果
    ShowMessage(output);
  finally
    httpclient.Free;
  end;
end;

场景2:需要使用异步避免阻塞主线程

需要将TNetHTTPClient声明为类成员变量延长生命周期,通过OnRequestCompleted回调处理请求结果,实现代码如下:
首先在窗体类中声明成员和回调方法:

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    FHttpClient: TNetHTTPClient;
    procedure RequestCompletedHandler(Sender: TObject; const AResponse: IHTTPResponse);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

对应实现部分:

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited;
  FHttpClient := TNetHTTPClient.Create(nil);
  FHttpClient.Asynchronous := True;
  // 绑定请求完成回调
  FHttpClient.OnRequestCompleted := RequestCompletedHandler;
end;

destructor TForm1.Destroy;
begin
  FHttpClient.Free;
  inherited;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  // 发起异步请求,不会阻塞主线程
  FHttpClient.Get('https://google.com');
end;

procedure TForm1.RequestCompletedHandler(Sender: TObject; const AResponse: IHTTPResponse);
var
  output: string;
begin
  if AResponse.StatusCode = 200 then
  begin
    output := AResponse.ContentAsString;
    // 回调运行在后台线程,更新UI需要同步到主线程
    TThread.Synchronize(nil,
      procedure
      begin
        ShowMessage(output);
      end
    );
  end;
end;
注意事项
  • 异步场景下不要提前销毁TNetHTTPClient实例,必须保证请求执行期间实例有效
  • 回调方法运行在后台线程,所有UI操作必须通过TThread.Synchronize或TThread.Queue同步到主线程执行,否则会触发跨线程访问异常
  • 可额外绑定OnRequestError事件捕获异步请求过程中的网络异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:06:00