完成源示例
本主题演示如何创作和使用自己的完成源类,类似于 .NET 的 TaskCompletionSource。
completion_source 示例的源代码
下面的列表中的代码作为示例提供。 其目的是说明如何编写自己的版本。 例如,支持取消和错误传播不在此示例的范围内。
#include <winrt/base.h>
#include <windows.h>template <typename T>
struct completion_source
{completion_source(){m_signal.attach(::CreateEvent(nullptr, true, false, nullptr));}void set(T const& value){m_value = value;::SetEvent(m_signal.get());}bool await_ready() const noexcept{return ::WaitForSingleObject(m_signal.get(), 0) == 0;}void await_suspend(std::experimental::coroutine_handle<> resume){m_wait.attach(winrt::check_pointer(::CreateThreadpoolWait(callback, resume.address(), nullptr)));::SetThreadpoolWait(m_wait.get(), m_signal.get(), nullptr);}T await_resume() const noexcept{return m_value;}private:static void __stdcall callback(PTP_CALLBACK_INSTANCE, void* context, PTP_WAIT, TP_WAIT_RESULT) noexcept{std::experimental::coroutine_handle<>::from_address(context)();}struct wait_traits{using type = PTP_WAIT;static void close(type value) noexcept{::CloseThreadpoolWait(value);}static constexpr type invalid() noexcept{return nullptr;}};winrt::handle m_signal;winrt::handle_type<wait_traits> m_wait;T m_value{};
};
将完成卸载到单独的协同程序
本部分演示 completion_source 的一个用例。 在 Visual Studio 中创建一个基于 Windows 控制台应用程序 (C++/WinRT) 项目模板的新项目,然后将以下代码清单粘贴到 main.cpp
(根据上一节中的列表展开 completion_source 的定义)。
// main.cpp
#include "pch.h"#include <winrt/base.h>
#include <windows.h>template <typename T>
struct completion_source
{//构造函数completion_source(){m_signal.attach(::CreateEvent(nullptr, true, false, nullptr));}void set(T const& value){m_value = value;::SetEvent(m_signal.get());//将指定的事件对象设置为信号状态。}//准备bool await_ready() const noexcept{return ::WaitForSingleObject(m_signal.get(), 0) == 0;//等待指定的对象处于信号状态或超时间隔已过。若要进入可警报等待状态,请使用 WaitForSingleObjectEx 函数。 若要等待多个对象,请使用 WaitForMultipleObjects。}//暂停void await_suspend(std::experimental::coroutine_handle<> resume){//CreateThreadpoolWait:创建新的等待对象。//参数1:[in] pfnwa 等待完成或超时时要调用的回调函数。//参数2:[in, out, optional] pv 要传递给回调函数的可选应用程序定义数据。//参数3:[in, optional] pcbe 定义执行回调的环境 的TP_CALLBACK_ENVIRON 结构。 InitializeThreadpoolEnvironment 函数返回此结构。如果此参数为 NULL,则回调在默认回调环境中执行。 有关详细信息,请参阅 InitializeThreadpoolEnvironment。m_wait.attach(winrt::check_pointer(::CreateThreadpoolWait(callback, resume.address(), nullptr)));::SetThreadpoolWait(m_wait.get(), m_signal.get(), nullptr);//设置 wait 对象,替换上一个等待对象(如果有)。 工作线程在句柄发出信号后或在指定的超时过期后调用 wait 对象的回调函数。}//返回m_valueT await_resume() const noexcept{return m_value;}private://回调函数static void __stdcall callback(PTP_CALLBACK_INSTANCE, void* context, PTP_WAIT, TP_WAIT_RESULT) noexcept{std::experimental::coroutine_handle<>::from_address(context)();}struct wait_traits{using type = PTP_WAIT;//释放指定的等待对象valuestatic void close(type value) noexcept //noexcept:指定某个函数是否可能会引发异常{::CloseThreadpoolWait(value);//释放指定的等待对象。}//返回空指针static constexpr type invalid() noexcept //constexpr:它表示 constant(常数)表达式。 与 const 一样,它可以应用于变量:如果任何代码试图 modify(修改)该值,将引发编译器错误。{return nullptr; }};winrt::handle m_signal; //会话句柄winrt::handle_type<wait_traits> m_wait;T m_value{};
};using namespace winrt;
using namespace Windows::Foundation;
using namespace std::literals;fire_and_forget CompleteAfterFiveSecondsAsync(completion_source<bool>& completionSource)
{co_await 5s;completionSource.set(true);
}IAsyncAction CompletionSourceExample1Async()
{completion_source<bool> completionSource;CompleteAfterFiveSecondsAsync(completionSource);co_await completionSource;
}int main()
{auto asyncAction{ CompletionSourceExample1Async() };puts("waiting");asyncAction.get();puts("done");
}
将 completion_source 封装在类中,并返回一个值
在下一个示例中,使用简单的 App 类封装 completion_source,并在完成时返回值。 在 Visual Studio 中创建一个基于 Windows 控制台应用程序 (C++/WinRT) 项目模板的新项目,然后将以下代码清单粘贴到 main.cpp
(根据上一节中的列表展开 completion_source 的定义)。
// main.cpp
#include "pch.h"#include <winrt/base.h>
#include <windows.h>template <typename T>
struct completion_source
{//构造函数completion_source(){m_signal.attach(::CreateEvent(nullptr, true, false, nullptr));}void set(T const& value){m_value = value;::SetEvent(m_signal.get());//将指定的事件对象设置为信号状态。}//准备bool await_ready() const noexcept{return ::WaitForSingleObject(m_signal.get(), 0) == 0;//等待指定的对象处于信号状态或超时间隔已过。若要进入可警报等待状态,请使用 WaitForSingleObjectEx 函数。 若要等待多个对象,请使用 WaitForMultipleObjects。}//暂停void await_suspend(std::experimental::coroutine_handle<> resume){//CreateThreadpoolWait:创建新的等待对象。//参数1:[in] pfnwa 等待完成或超时时要调用的回调函数。//参数2:[in, out, optional] pv 要传递给回调函数的可选应用程序定义数据。//参数3:[in, optional] pcbe 定义执行回调的环境 的TP_CALLBACK_ENVIRON 结构。 InitializeThreadpoolEnvironment 函数返回此结构。如果此参数为 NULL,则回调在默认回调环境中执行。 有关详细信息,请参阅 InitializeThreadpoolEnvironment。m_wait.attach(winrt::check_pointer(::CreateThreadpoolWait(callback, resume.address(), nullptr)));::SetThreadpoolWait(m_wait.get(), m_signal.get(), nullptr);//设置 wait 对象,替换上一个等待对象(如果有)。 工作线程在句柄发出信号后或在指定的超时过期后调用 wait 对象的回调函数。}//返回m_valueT await_resume() const noexcept{return m_value;}private://回调函数static void __stdcall callback(PTP_CALLBACK_INSTANCE, void* context, PTP_WAIT, TP_WAIT_RESULT) noexcept{std::experimental::coroutine_handle<>::from_address(context)();}struct wait_traits{using type = PTP_WAIT;//释放指定的等待对象valuestatic void close(type value) noexcept //noexcept:指定某个函数是否可能会引发异常{::CloseThreadpoolWait(value);//释放指定的等待对象。}//返回空指针static constexpr type invalid() noexcept //constexpr:它表示 constant(常数)表达式。 与 const 一样,它可以应用于变量:如果任何代码试图 modify(修改)该值,将引发编译器错误。{return nullptr; }};winrt::handle m_signal; //会话句柄winrt::handle_type<wait_traits> m_wait;T m_value{};
};using namespace winrt;
using namespace Windows::Foundation;
using namespace std::literals;struct App
{completion_source<winrt::hstring> m_completionSource;IAsyncOperation<winrt::hstring> CompletionSourceExample2Async(){co_return co_await m_completionSource;}winrt::fire_and_forget CompleteAfterFiveSecondsAsync(){co_await 5s;m_completionSource.set(L"Hello, World!");}
};int main()
{App app;auto asyncAction{ app.CompletionSourceExample2Async() };app.CompleteAfterFiveSecondsAsync();puts("waiting");auto message = asyncAction.get();printf("%ls\n", message.c_str());
}
相关文章:

完成源示例
本主题演示如何创作和使用自己的完成源类,类似于 .NET 的 TaskCompletionSource。 completion_source 示例的源代码 下面的列表中的代码作为示例提供。 其目的是说明如何编写自己的版本。 例如,支持取消和错误传播不在此示例的范围内。 #include <w…...
业务和流程的关系
背景 概念不清,沟通就容易出现问题,最可怕会出现跑偏情况如何解决,数字化落地过程,程序是死的,最怕灵活,所以在沟通和编码,设计中,很重要的一点就是解决概念,澄清问题&a…...

【河海大学论文LaTeX+VSCode全指南】
河海大学论文LaTeXVSCode全指南 前言一、 LaTeX \LaTeX{} LATEX的安装二、VScode的安装三、VScode的配置四、验证五、优化 前言 LaTeX \LaTeX{} LATEX在论文写作方面具有传统Word无法比拟的优点,VScode作为一个轻量化的全功能文本编辑器,由于其极强的…...

学习python仅此一篇就够了(文件操作:读,写,追加)
python文件操作 文件编码 编码技术即:翻译的规则,记录了如何将内容翻译成二进制,以及如何将二进制翻译回可识别内容。 计算机中有许多可用编码: UTF-8 GBK BUG5 文件的读取操作 open()函数 在pyth…...
vue中 ref 和 $refs的使用
1. 作用 利用 ref 和 $refs 可以用于 获取 dom 元素, 或 组件实例 2. 获取 dom 使用步骤: 2.1 目标标签添加属性 :ref <div ref"chartRef">我是渲染图表的容器</div>2.2 通过$ref:获取标签 mounted() {console.log(this.$re…...

Centos7升级openssl到openssl1.1.1
Centos7升级openssl到openssl1.1.1 1、先查看openssl版本:openssl version 2、Centos7升级openssl到openssl1.1.1 升级步骤 #1、更新所有现有的软件包列表并安装最新的软件包: $sudo yum update #2、接下来,我们需要从源代码编译和构建OpenS…...

uniapp中实现H5录音和上传、实时语音识别(兼容App小程序)和波形可视化
文章目录 Recorder-UniCore插件特性集成到项目中调用录音上传录音ASR语音识别 在uniapp中使用Recorder-UniCore插件可以实现跨平台录音功能,uniapp自带的recorderManager接口不支持H5、录音格式和实时回调onFrameRecorded兼容性不好,用Recorder插件可避免…...

HashMap集合万字源码详解(面试常考)
文章目录 HashMap集合1.散列2.hashMap结构3.继承关系4.成员变量5.构造方法6.成员方法6.1增加方法6.2将链表转换为红黑树的treeifyBin方法6.3扩容方法_resize6.3.1扩容机制6.3.2源码resize方法的解读 6.4 删除方法(remove)6.5查找元素方法(get)6.6遍历HashMap集合几种方式 7.初始…...
LeetCode1124. Longest Well-Performing Interval
文章目录 一、题目二、题解 一、题目 We are given hours, a list of the number of hours worked per day for a given employee. A day is considered to be a tiring day if and only if the number of hours worked is (strictly) greater than 8. A well-performing in…...

如何使用手机公网远程访问本地群辉Video Station中视频文件【内网穿透】
最近,我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念,而且内容风趣幽默。我觉得它对大家可能会有所帮助,所以我在此分享。点击这里跳转到网站。 文章目录 1.使用环境要求:2.下载群晖videostation&am…...

事件分析应急响应-Server2229(环境+解析)
任务环境说明: 服务器场景:Server2229(开放链接)用户名:root,密码:...

SpringCloud:微服务
文章目录 微服务服务架构演变单例架构(集中式架构)分布式架构 微服务SpringCloud 微服务 服务架构演变 单例架构(集中式架构) 单例架构: 将业务的所有功能集中在一个项目中开发,打成一个包部署 优点&…...
拥抱Guava之集合操作
深入Guava集合操作 在Java开发中,Google Guava库是处理集合的强大工具。起源于Google内部需求,Guava以简洁性、性能优化为理念,提供高效不可变集合和实用工具类。本文深入剖析Guava的核心功能,为开发者呈现集合操作的全新视角&am…...

运算放大器相关知识总结(1)
1、 前言 最近做了一个小项目,这个项目是研发一款阻抗测量仪。这个阻抗测量仪可以测量人体在不同频率下的生物电阻抗,该设备的核心是模拟电路,技术难点是减小模拟电路噪声。该项目前前忙了2个多月,借着研发这个项目的机会把自己掌…...

ZMQ_REQ\REP模式
文章内容: 学习ZMQ库中REQ\REP模式相关的内容 简介 应答模式:REQ(客户端)和REP(服务端) 典型的一问一答协议,即客户端需要首先发送hello,服务器则返回word,若客户端发…...

机器人跟踪性能量化指标
衡量机械臂关节轨迹跟踪控制的性能可以通过以下几个方面来进行: 跟踪精度:这是衡量机械臂关节轨迹跟踪控制性能的最重要的指标。它反映了机械臂实际运动轨迹与期望运动轨迹之间的偏差。跟踪精度越高,说明机械臂的控制性能越好。运动范围&…...

【GitHub项目推荐--开源的坦克大战】【转载】
坦克大战当年红遍大江南北,很多和我一样的九零后应该都有着对这个游戏的记忆。现在显示器分辨率越来越高,使用矢量图来实现像素风格游戏,可以获得非常高的展现质量。 这个项目是作者肥超花了很长时间折腾的复刻版本,所有元素都使…...

06、Kafka ------ 各个功能的作用解释(ISR 同步副本、非同步副本、自动创建主题、修改主题、删除主题)
目录 CMAK 各个功能的作用解释★ ISR副本 (同步副本)★ 非同步副本★ 自动创建主题★ 修改主题★ 删除主题 CMAK 各个功能的作用解释 ★ ISR副本 (同步副本) 简单来说 ,ISR 副本 就是 Kafka 认为与 领导者副本 同步的副本。 ISR࿰…...
Spring Security实现详解
一、WebSecurityConfigurerAdapter 总配置类: 1、介绍:配置类 2、主要方法: (1)configure(HttpSecurity http) protected void configure(HttpSecurity http) throws Exception {this.logge…...
⭐Unity LeapMotion与手的相关开发
LeapMotion 官方文档中文翻译帮助手册教程 Hand 一个Hand手对象表示了一个跟踪的手,一个手总是包含5个手指以及相关属性如:Direction,PalmPosition,和Basis(orientation). lamPosition :手掌中心到Leap设备原点以毫米测量的距离 PalmVelocity :手掌移…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...