本文介绍了如何使用"WinHttp.WinHttpRequest.5.1";异步地?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码:

var
  WinHttpReq: OleVariant;

procedure TForm1.Button1Click(Sender: TObject);
begin
  WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
  WinHttpReq.Open('GET', 'http://stackoverflow.com', TRUE); // asynchronously
  WinHttpReq.setRequestHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0');
  WinHttpReq.Send();
  // HOW to set a callback procedure here and get the response?
end;

注意:我不想导入mshttp.dll并使用TLB.我想通过后期绑定使用它.我也想处理异常(如果有).

Note: I do not want to import mshttp.dll and use TLB. I want to use it via late binding. I also would like to handle exceptions if any.

我接受TLama的回答,因为它为我最初提出的要求提供了一个很好的选择.加上它有一个很好的示例源.

I'm accepting TLama's answer becouse it gives me a good alternative to what I initially was asking. plus it has a good example source.

这是(附带源代码).

Here is a very nice implementation of WinHTTPRequest Wrapper with IConnectionPoint for Events (source code is attached).

推荐答案

正如Stijn在他的回答中所说,为了防止程序滞后,请使用线程. IWinHttpRequest.Open 也具有异步配置功能,但是要捕获事件和 IWinHttpRequest.WaitForResponse 甚至会卡住您的程序.

As Stijn said in his answer, to prevent your program to lag, use the threads. IWinHttpRequest.Open has the asynchronous configuration capability too but it would be very difficult to catch the events and IWinHttpRequest.WaitForResponse would stuck your program even so.

这是如何将响应文本放入表单的备注框中的简单示例.请注意,以下示例使用同步模式,并且您还可以使用 IWinHttpRequest.SetTimeouts .如果您想像问题一样使用异步模式,则必须等待 IWinHttpRequest.WaitForResponse 方法.

Here is the simple example of how to get the response text into the form's memo box.Please note that the following example uses the synchronous mode and that you can additionally modify the timeout values using IWinHttpRequest.SetTimeouts. If you want to use the asynchronous mode as you have in your question then you'll have to wait for the result with IWinHttpRequest.WaitForResponse method.

///////////////////////////////////////////////////////////////////////////////
/////   WinHttpRequest threading demo unit   //////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

unit WinHttpRequestUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ActiveX, ComObj, StdCtrls;

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

var
  Form1: TForm1;

implementation

{$R *.dfm}

///////////////////////////////////////////////////////////////////////////////
/////   THTTPRequest - TThread descendant for single request   ////////////////
///////////////////////////////////////////////////////////////////////////////

type
  THTTPRequest = class(TThread)
  private
    FRequestURL: string;
    FResponseText: string;
    procedure Execute; override;
    procedure SynchronizeResult;
  public
    constructor Create(const RequestURL: string);
    destructor Destroy; override;
  end;

///////////////////////////////////////////////////////////////////////////////
/////   THTTPRequest.Create - thread constructor   ////////////////////////////
///////////////////////////////////////////////////////////////////////////////

// RequestURL - the requested URL

constructor THTTPRequest.Create(const RequestURL: string);
begin
  // create and start the thread after create
  inherited Create(False);
  // free the thread after THTTPRequest.Execute returns
  FreeOnTerminate := True;
  // store the passed parameter into the field for future use
  FRequestURL := RequestURL;
end;

///////////////////////////////////////////////////////////////////////////////
/////   THTTPRequest.Destroy - thread destructor   ////////////////////////////
///////////////////////////////////////////////////////////////////////////////

destructor THTTPRequest.Destroy;
begin
  inherited;
end;

///////////////////////////////////////////////////////////////////////////////
/////   THTTPRequest.Execute - thread body   //////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

procedure THTTPRequest.Execute;
var
  Request: OleVariant;
begin
  // COM library initialization for the current thread
  CoInitialize(nil);
  try
    // create the WinHttpRequest object instance
    Request := CreateOleObject('WinHttp.WinHttpRequest.5.1');
    // open HTTP connection with GET method in synchronous mode
    Request.Open('GET', FRequestURL, False);
    // set the User-Agent header value
    Request.SetRequestHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0');
    // sends the HTTP request to the server, the Send method does not return
    // until WinHTTP completely receives the response (synchronous mode)
    Request.Send;
    // store the response into the field for synchronization
    FResponseText := Request.ResponseText;
    // execute the SynchronizeResult method within the main thread context
    Synchronize(SynchronizeResult);
  finally
    // release the WinHttpRequest object instance
    Request := Unassigned;
    // uninitialize COM library with all resources
    CoUninitialize;
  end;
end;

///////////////////////////////////////////////////////////////////////////////
/////   THTTPRequest.SynchronizeResult - synchronization method   /////////////
///////////////////////////////////////////////////////////////////////////////

procedure THTTPRequest.SynchronizeResult;
begin
  // because of calling this method through Synchronize it is safe to access
  // the VCL controls from the main thread here, so let's fill the memo text
  // with the HTTP response stored before
  Form1.Memo1.Lines.Text := FResponseText;
end;

///////////////////////////////////////////////////////////////////////////////
/////   TForm1.Button1Click - button click event   ////////////////////////////
///////////////////////////////////////////////////////////////////////////////

// Sender - object which invoked the event

procedure TForm1.Button1Click(Sender: TObject);
begin
  // because the thread will be destroyed immediately after the Execute method
  // finishes (it's because FreeOnTerminate is set to True) and because we are
  // not reading any values from the thread (it fills the memo box with the
  // response for us in SynchronizeResult method) we don't need to store its
  // object instance anywhere as well as we don't need to care about freeing it
  THTTPRequest.Create('http://stackoverflow.com');
end;

end.

这篇关于如何使用"WinHttp.WinHttpRequest.5.1";异步地?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-29 12:23
查看更多