gpt4 book ai didi

multithreading - 如何异步使用 "WinHttp.WinHttpRequest.5.1"?

转载 作者:行者123 更新时间:2023-12-03 15:26:02 27 4
gpt4 key购买 nike

代码:

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。我想通过后期绑定(bind)使用它。我还想处理异常(如果有)。

编辑:我接受 TLama 的回答,因为它为我提供了一个很好的替代方案来替代我最初提出的问题。另外它还有一个很好的示例源。

这是 WinHTTPRequest Wrapper with IConnectionPoint for Events 的一个非常好的实现。 (附源代码)。

最佳答案

正如 Stijn 在他的回答中所说,为了防止程序滞后,请使用线程。 IWinHttpRequest.Open也具有异步配置功能,但捕获事件非常困难,IWinHttpRequest.WaitForResponse即使如此,你的程序也会卡住。

以下是如何将响应文本放入表单的备注框中的简单示例。请注意,以下示例使用同步模式,您还可以使用 IWinHttpRequest.SetTimeouts 修改超时值。 。如果您想像问题中那样使用异步模式,那么您必须等待 IWinHttpRequest.WaitForResponse 的结果。方法。

///////////////////////////////////////////////////////////////////////////////
///// 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.

关于multithreading - 如何异步使用 "WinHttp.WinHttpRequest.5.1"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8547188/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com