如何异步使用“WinHttp.WinHttpRequest.5.1”?

2023-12-19

代码:

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

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

这是一个非常好的实现带有 IConnectionPoint 事件的 WinHTTPRequest 包装器 https://forums.embarcadero.com/thread.jspa?messageID=168727(附上源代码)。


正如 Stijn 在他的回答中所说,为了防止程序滞后,请使用线程。IWinHttpRequest.Open http://msdn.microsoft.com/en-us/library/windows/desktop/aa383989%28v=vs.85%29.aspx也有异步配置能力,但是很难捕获事件和IWinHttpRequest.WaitForResponse http://msdn.microsoft.com/en-us/library/windows/desktop/aa384064%28v=vs.85%29.aspx即使如此,你的程序也会卡住。

以下是如何将响应文本放入表单的备注框中的简单示例。 请注意,以下示例使用同步模式,您还可以使用以下命令修改超时值IWinHttpRequest.SetTimeouts http://msdn.microsoft.com/en-us/library/windows/desktop/aa384061%28v=VS.85%29.aspx。如果您想像问题中那样使用异步模式,那么您必须等待结果IWinHttpRequest.WaitForResponse http://msdn.microsoft.com/en-us/library/windows/desktop/aa384064%28v=vs.85%29.aspx 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.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何异步使用“WinHttp.WinHttpRequest.5.1”? 的相关文章

  • 运行多线程时双重释放或损坏

    我在 C 程序中遇到运行时错误 双重释放或损坏 该程序调用可靠的库 ANN 并使用 OpenMP 并行化 for 循环 glibc detected home tim test debug test double free or corru
  • 判断线程是否已经启动

    如何判断Python线程是否已经启动 有一个方法is alive 但这是真的before and while一个线程正在运行 你可以看看ident领域的Thread实例 这Python 2 7 线程文档 http docs python o
  • Delphi 的免费加密库 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在为 Delphi 2010 寻找一个免费且最新的加密库 该库实现 RSA 和 AES Rijnda
  • 为什么 std::atomic 比 volatile bool 慢很多?

    多年来我一直使用 volatile bool 来控制线程执行 并且效果很好 in my class declaration volatile bool stop In the thread function while stop do th
  • 使用 C# 的异步 WebRequest

    您好 我有一个函数 它将 url Get 参数传递到网络服务器上的 php 文件 并等待文件的响应 通常需要 10 20 秒 我想将其放入一个循环中 因为我必须一次将这些 Get 请求发送到大约 5 个不同的 php 文件 但是当我尝试将其
  • 基础设施 - 同步和异步接口和实现? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在实现库 基础设施时 并且该 API 的用户希望同步和异步使用代码 我读到混合同步和异步并不是一个好主意 例如 同步实现包括等待异步实现 显然
  • 如何追踪手柄泄漏?

    在我的一个应用程序中 我观察到句柄数量不断增加 在不使用应用程序的情况下 该数字大约每秒增加一次 因此后台处理代码的某些部分一定存在句柄泄漏 我如何追踪此类泄漏 有什么工具可以帮助解决这个问题吗 跟踪句柄泄漏时要寻找哪些模式 导致手柄泄漏的
  • Delphi XE5 REST/Android 客户端“会话已过期”

    我有一个REST Server与Android Client 都在Deplhi Xe5 Android客户端成功连接Rest服务器 在我的服务器中我有一个TDSHttpWebDispatcher with SessionTimeout 12
  • 重构——套接字中的良好实践——简单的服务器-客户端 Swing 应用程序

    我使用单例和观察者模式编写了一个带有 Swing 接口的简单服务器 客户端程序 每个客户端都连接到服务器并可以发送消息 服务器将其收到的消息转发给其余的客户端 客户端使用 GUI 允许它们随时连接和断开与服务器的连接 该程序运行得很好 因为
  • Delphi中的抽象类

    我正在使用一个具有许多抽象类的组件套件 现在我想应用多态性 但在创建对象时收到错误抽象类 即使我不需要 我是否应该重写所有虚拟方法 有什么解决方法或解决方案吗 为了创建类的实例 您需要重写所有声明为虚拟抽象的方法 即使您不使用它们 如果您确
  • async wait 在调用异步方法时返回 Task> 而不是 List

    我正在尝试了解 async wait 的用法 并且研究了一些博客文章 现在我已经编写了一个测试代码 但它没有按照我期望的方式工作 我有一个返回列表的方法 private List
  • Nodejs 异步 Promise 队列

    我需要使用速率受限的 API 例如 我一秒钟只能进行 10 个 API 调用 因此我需要等待当前秒结束才能进行另一个 API 调用 为了实现这一目标 我想创建一个可以自行管理的异步队列 它的主要功能是让我向队列添加一个新的 Promise
  • C# 的空条件委托调用线程安全吗? [复制]

    这个问题在这里已经有答案了 这就是我一直以来编写事件引发者的方式 例如属性更改 public event PropertyChangedEventHandler PropertyChanged private void RaisePrope
  • 在多线程环境中,Collections.sort 方法有时会抛出 ConcurrentModificationException。列表没有进行结构性修改

    package CollectionsTS import java util ArrayList import java util Collections import java util HashSet import java util
  • 如何追踪“地址 00000000”的访问违规

    我知道如何创建 map 文件来在错误消息包含实际地址时跟踪访问冲突错误 但是如果错误消息说怎么办 Access violation at address 00000000 Read of address 00000000 我从哪里开始寻找这
  • Node.js 工作线程中的 I/O 性能

    下面是一个工作线程示例 在本地计算机上同步 I O 大约需要 600 毫秒 const fs require fs const isMainThread Worker parentPort workerData require worker
  • 为什么 .NET 异步等待文件复制比同步 File.Copy() 调用消耗更多 CPU?

    为什么下面的代码会产生 public static class Program public static void Main params string args var sourceFileName C Users ehoua Desk
  • Android:等待 firebase valueEventListener

    我正在尝试使用信号量来等待我的 firebase valueEventListener 我有一个用户信息活动 其中包含用户必须填写的 6 个不同字段 当用户保存他 她的信息时 我想进行 全有或全无 类型的检查 某些用户信息不能重复 例如用户
  • 使用 Thread.Sleep() 时,异步编程如何与线程一起工作?

    假设 前言 在之前的问题中 我们注意到Thread Sleep阻塞线程参见 什么时候使用Task Delay 什么时候使用Thread Sleep https stackoverflow com questions 20082221 whe
  • c++11 中的 std::thread 问题

    我在尝试从标准模板库编译具有多线程的程序时遇到一些麻烦 当我尝试编译以下程序时 它返回一个晦涩的错误 include

随机推荐

  • 快速检查长整型是否为立方体的方法(Java 中)

    我正在编写一个程序 其中需要检查某些大数 立方体的排列 是否是三次方 对于某些n等于n 3 目前我只是使用该方法 static boolean isCube long input double cubeRoot Math pow input
  • 是否可以通过 RDCOM 发送可视化结果?

    我对 R 编程相对较新 并且已经开展了一个小项目来向 R 世界介绍自己 我想做的是帮助我的一位同事自动化他每周都会执行的手动电子邮件流程 该电子邮件包含用 Excel 创建的图表 DOW 指数价格 我们公司的股票价格以及他每周手动更新的一些
  • 使用 Sed 将旧时间戳替换为当前时间戳

    我想使用 Sed 在 template php 文件中查找 JS 文件名称的 unix 时间戳部分 并将其替换为当前时间戳 旧时间戳会有所不同 因此我需要一个正则表达式来匹配数字 这是我到目前为止所拥有的 TimPeterson curre
  • C# 中修饰符的顺序有约定吗?

    如果我要使用多个修饰符关键字 我应该按什么顺序使用 例如 public private protected virtual abstract override new static internal sealed 以及我忘记的任何其他人 我
  • 为什么 OpenXML 读取行两次

    我计算两个工作表中的行数 如下所示 foreach WorksheetPart worksheetPart in workbookPart WorksheetParts OpenXmlPartReader reader new OpenXm
  • 当 selectedItem 为 null 时,在 Combobox 中显示“选择一项”

    我有一个绑定到 viewModel 对象列表的 WPF 组合框 最初 SelectedItem 为空 因此组合框显示为空白 当所选项目为空时 我希望组合框显示 选择项目 以引导用户从组合框中选择某些内容 有点像这样 一些文本框包含灰色文本
  • Flexbox 中的行换行中心对齐

    目前 我正在尝试使用 Flexbox 将列居中 但当我调整浏览器大小时 它会粘在左侧 我尝试过调整内容中心和对齐项目中心 但我可能没有将它们放在正确的位置 如果有人知道如何解决这个问题 将不胜感激 谢谢你 wrap display flex
  • 无法完成交付

    我在尝试完成已发布的交付时收到以下错误 我可以从目标网站做些什么吗 cleartool Error Unable to check out vobs amit sumit lost found pcs i ltf odfc set sftp
  • 如何使用 javaparser 获取类级别变量声明?

    我只想获取类级别的变量声明 如何使用 javaparser 获取声明 public class Login private Keyword browser private String pageTitle Login 使用javaparse
  • 为 GridView 添加捏缩放功能

    我需要为该 gridview 添加捏缩放 我没有找到任何有关在 gridview 中添加捏缩放的示例 到目前为止 我的布局如下所示 我需要向该 gridview 添加捏缩放 活动 main xml
  • 张量流中的CUDA_ERROR_OUT_OF_MEMORY

    当我开始训练一些神经网络时 它满足了CUDA ERROR OUT OF MEMORY但训练可以继续进行 不会出现错误 因为我想根据实际需要使用GPU内存 所以我设置了gpu options allow growth True 日志如下 I
  • 如何超链接到 .ppt 文件的特定幻灯片?

    我想链接到在线 PowerPoint 文件中的特定幻灯片 例如http www example com hello ppt 但我想要的是 当人们点击我的链接时 它会直接转到第 n 张幻灯片 这可能吗 Link to http www wha
  • html2canvas 不渲染 CDN 图像

    我正在尝试使用 html2canvas 获取屏幕截图 它对于文本工作正常 但它不渲染 CDN 图像 如果我在服务器中托管图像 它工作正常 但如果尝试从 CDN 链接加载图像 则这些图像不会渲染 我的代码是 索引 php div img sr
  • 从 Android 应用程序共享图像

    我正在尝试分享我的 Android 应用程序中的图像 我正在尝试将其作为电子邮件附件以及 WhatsApp 上的照片发送 代码是 String imageUrl Path to image eg sdcard pictures image1
  • 在 Django 数据库中存储整数数组

    在 django 数据库中存储整数数组的最佳方法是什么 我正在使用数组字段 https docs djangoproject com en 2 1 ref contrib postgres fields querying arrayfiel
  • Python,argparse:如何使 nargs=2 与 type=str 和 type=int

    我花了一些时间在 argparse 文档上 但我仍然在为我的程序中的一个选项使用这个模块而苦苦挣扎 parser add argument r rmsd dest rmsd nargs 2 help extract the poses th
  • Vagrant 配置错误 - “必须指定一个框。”

    盒子工作得很好 然后我停止了其中一个 当时唯一一个正在运行的 现在我无法让它们中的任何一个恢复 Running vagrant up name 给我以下错误 无论我选择哪个或是否将其保留在vagrant up让他们俩都出现 There ar
  • 头文件中的 Lambda 错误

    在我的一堂课上 我尝试使用std priority queue与指定的 lambda 进行比较 pragma once include
  • 将变量注入回调函数作用域

    是否可以将变量添加到回调范围 我想要实现的是 Foo prototype bar function fn var baz baz fn call this Foo bar function console log baz gives baz
  • 如何异步使用“WinHttp.WinHttpRequest.5.1”?

    代码 var WinHttpReq OleVariant procedure TForm1 Button1Click Sender TObject begin WinHttpReq CreateOleObject WinHttp WinHt