评论

收藏

[R语言] Delphi 10.3.1 TNetHttpClient在多线程中存在的问题及解决方法。

编程语言 编程语言 发布于:2021-07-31 10:16 | 阅读数:412 | 评论:0

Delphi 10.3.1发布了,对10.3.0存在的各种问题,做了大量的修正。但听高勇说TNetHttpClient在多线程中存在问题,今天做了一下测试,确实如此,看来,还需要官方进一步修正!
具体测试方法,直接上代码:
procedure TForm1.Button3Click(Sender: TObject);
var
  i: Integer;
begin
  for i := 1 to 3 do // 大于2,无法测试通过.
  begin
  TThread.CreateAnonymousThread(
    procedure()
    var
    aHttpClient: TNethttpClient;
    AResponseContent: Tstream;
    cnt: Integer;
    ContentLength: Integer;
    tid:Cardinal;
    begin
    cnt := 0;
    tid:=TThread.Current.ThreadID;
    aHttpClient := TNethttpClient.Create(Self);//建立NetHttpClient实例,并用他不断的访问同一网址。
    try
      while true do
      begin
      Inc(cnt);
      // aHttpClient := TNethttpClient.Create(Self);
      AResponseContent := TMemoryStream.Create;
      try
        aHttpClient.Accept := 'text/javascript, text/html, application/xml, text/xml, /';
        aHttpClient.AcceptLanguage := 'en-US,en;q=0.8,fr;q=0.6';
        aHttpClient.UserAgent := 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36';
        try
        aHttpClient.Get('https://www.cnblogs.com/kinglandsoft/p/10383103.html',AResponseContent);//开始访问并返回结果到AResponseContent流中.
        except
        On E: Exception do
        begin
          TThread.Synchronize(nil,
          procedure()
          begin
            if Memo1.Lines.Count > 500 then
            Memo1.Lines.Clear;
            Memo1.Lines.Add(E.Message);
          end);
        end;
        end;
        ContentLength := AResponseContent.Size;//取得返回内容的长度,用来显示
        TThread.Synchronize(nil,
        procedure()
        var
          s: string;
        begin
          s := Format('cnt=%d,ContentLength:%d in thread id:%s',
          [cnt, ContentLength, tid.ToString]);
          Label1.Text := s;
          Memo1.Lines.Add(s);
          if Memo1.Lines.Count > 500 then
          Memo1.Lines.Clear;
        end);
      finally
        // aHttpClient.Free;
        AResponseContent.Free;
      end;
      end; // while true.
    finally
      aHttpClient.Free;
    end;
    end).Start;
  end;
end;
实现思路,在线程中,建立一个NetHttpClient实例,用来访问一个网址,同时建立几个线程来运行NetHttpClient来访问。结果,如果实例数=2,可以通过,大于2,则无法通过。另外换成HttpClient也是同样的情况。此外,只是在android平台存在问题,win32平台正常。
向官方提交了这个问题,地址在https://quality.embarcadero.com/browse/RSP-23742,如果你也遇到,别忘记投一票,督促官方确认并修正。
跳过该问题的办法,在官方没有修正前,可以使用idHTTP来替代。
有解决方案了:
复制System.Net.HttpClient.pas单元到你的项目文件夹,修改THTTPClientExt的记录结构为如下代码:
THTTPClientExt = record
  case Integer of
  0: (
    FPreemptiveAuthentication: Boolean;
    FSecureFailureReasons: THTTPSecureFailureReasons;
    FAutomaticDecompression: THTTPCompressionMethods
  );
  1: (
    _pad: array[0 .. 7] of Byte
  );
  end;
测试通过。
另外,如果不复制System.Net.HttpClient.pas到你的项目目录,则需要把System.Net.HttpClient.pas所在目录加入项目的Search Path中。
DSC0000.png



关注下面的标签,发现更多相似文章