提出http请求的最佳方法是什么

时间:2016-07-26 04:01:43

标签: http delphi delphi-xe7

执行此操作的最佳方法是什么:我有一个填充了Web地址的txt文件,我必须使用idHTTP组件检查所有这些文件,只需从Web服务器进行简单检查,下载html并查找匹配项,我希望它快,有不同类型的线程,我不确定最好使用什么,TParallel forTask threads或常规线程? 我在TParallel for之前尝试过,我遇到了AV,我也试过Task threads但是它不快,http请求变得越来越慢,我也尝试了常规线程,我不知道如何使用它因为使用起来很复杂 注意:请不要downvote我只需要专家的建议。谢谢

2 个答案:

答案 0 :(得分:1)

第一条建议:不要使用Indy。使用THTTPClient(单位System.Net.HttpClient) - 本机用于Delphi XE?+

我还在使用旧的TThreads。我只能用TThread提出建议。

工作流:

主线程 - 逐行读取TXT文件。 在线路被引入之后,您创建了新线程,它正在从WWW下载信息。

申请样本:

unit ufmMain;

interface

uses
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants,
  { TThread }
  System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TLoad = class(TThread)
  protected
    FURL,
    FOutputFileName: String;

    procedure Execute; override;
  public
    constructor Create(const AURL, AOutputFileName: String); overload;
  end;

  HTTP = class
  public
    class procedure Get(const AURL: String; out AOutputStream: TMemoryStream);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  { THTTPClient }
  System.Net.HttpClient;

procedure TForm1.Button1Click(Sender: TObject);
var
  LLoad: TLoad;
  LFile: TextFile;
  LCycle: Integer;
  LUrl: String;
begin
  LCycle := 0;

  AssignFile(LFile, 'urls.txt');
  try
    Reset(LFile);

    while not Eof(LFile) do
      begin
        { Using for generate file name. All file names must be unique }
        Inc(LCycle);

        { Read next URL }
        ReadLn(LFile, LUrl);

        { Create new thread }
        LLoad := TLoad.Create(LUrl, 'Output file No ' + LCycle.ToString + '.htm');
        LLoad.FreeOnTerminate := True;
        LLoad.Start;
      end;
  finally
    CloseFile(LFile);
  end;
end;

{ TLoad }

constructor TLoad.Create(const AURL, AOutputFileName: String);
begin
  inherited Create(True);

  FURL := AURL;
  FOutputFileName := AOutputFileName;
end;

procedure TLoad.Execute;
var
  LResponse: TMemoryStream;
begin
  inherited;

  LResponse := TStringStream.Create;
  try
    HTTP.Get(FURL, LResponse);

    { Save result to file }
    LResponse.SaveToFile(GetCurrentDir + PathDelim + FOutputFileName);
  finally
    LResponse.Free;
  end;
end;

{ HTTP }

class procedure HTTP.Get(const AURL: String; out AOutputStream: TMemoryStream);
var
    LStream: TStream;
  LHTTPClient: THTTPClient;
begin
  LHTTPClient := THTTPClient.Create;
  try
    LStream := LHTTPClient.Get(AURL).ContentStream;

    AOutputStream.CopyFrom(LStream, LStream.Size);
  finally
    LHTTPClient.Free;
  end;
end;

end.

为什么我反对Indy:

1)THTTPClient不需要额外的DLL用于SSL协议

2)THTTPClient是现代的Delphi XE8

3)我的主观意见:THTTPClient工作得更顺利(问题少)然后是Indy库。我过去10年使用过Indy,但现在我支持的所有项目都转移到了THTTPClient。

答案 1 :(得分:0)

您可以使用TTask和Indy(TIdHTTP)。例如:

function GetUrl(const aUrl: string): ITask;
begin
  Result := TTask.Run(
    procedure
    var
      FOutput: string;
      FHTTP: TIdHTTP;
    begin
      FHTTP:=TIdHTTP.Create(nil);
      try
        try
          FOutput:=FHTTP.Get(aUrl);
        except
          // handle errors
        end;
      finally
        FHTTP.Free;
      end;

      TThread.Synchronize(nil,
        procedure
        begin
          ProcessOutput(FOutput); // send your output/result to main thread
        end);
    end );
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  list: TStringList;
begin
  list:=TStringList.Create;
  try
    list.LoadFromFile('yourfile.txt');

    // get all your urls
    // you should control how many threads run at the same time
    for i := 0 to list.Count-1 do
      GetUrl(list[i]);
  finally
    list.Free;
  end;
end;