完成源示例
本主题演示如何创作和使用自己的完成源类,类似于 .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 :手掌移…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...
webpack面试题
面试题:webpack介绍和简单使用 一、webpack(模块化打包工具)1. webpack是把项目当作一个整体,通过给定的一个主文件,webpack将从这个主文件开始找到你项目当中的所有依赖文件,使用loaders来处理它们&#x…...
欢乐熊大话蓝牙知识17:多连接 BLE 怎么设计服务不会乱?分层思维来救场!
多连接 BLE 怎么设计服务不会乱?分层思维来救场! 作者按: 你是不是也遇到过 BLE 多连接时,调试现场像网吧“掉线风暴”? 温度传感器连上了,心率带丢了;一边 OTA 更新,一边通知卡壳。…...
