当前位置: 首页 > news >正文

完成源示例

本主题演示如何创作和使用自己的完成源类,类似于 .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());
}

 

相关文章:

完成源示例

本主题演示如何创作和使用自己的完成源类&#xff0c;类似于 .NET 的 TaskCompletionSource。 completion_source 示例的源代码 下面的列表中的代码作为示例提供。 其目的是说明如何编写自己的版本。 例如&#xff0c;支持取消和错误传播不在此示例的范围内。 #include <w…...

业务和流程的关系

背景 概念不清&#xff0c;沟通就容易出现问题&#xff0c;最可怕会出现跑偏情况如何解决&#xff0c;数字化落地过程&#xff0c;程序是死的&#xff0c;最怕灵活&#xff0c;所以在沟通和编码&#xff0c;设计中&#xff0c;很重要的一点就是解决概念&#xff0c;澄清问题&a…...

【河海大学论文LaTeX+VSCode全指南】

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

学习python仅此一篇就够了(文件操作:读,写,追加)

python文件操作 文件编码 编码技术即&#xff1a;翻译的规则&#xff0c;记录了如何将内容翻译成二进制&#xff0c;以及如何将二进制翻译回可识别内容。 计算机中有许多可用编码&#xff1a; UTF-8 GBK BUG5 文件的读取操作 open&#xff08;&#xff09;函数 在pyth…...

vue中 ref 和 $refs的使用

1. 作用 利用 ref 和 $refs 可以用于 获取 dom 元素, 或 组件实例 2. 获取 dom 使用步骤&#xff1a; 2.1 目标标签添加属性 :ref <div ref"chartRef">我是渲染图表的容器</div>2.2 通过$ref&#xff1a;获取标签 mounted() {console.log(this.$re…...

Centos7升级openssl到openssl1.1.1

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

uniapp中实现H5录音和上传、实时语音识别(兼容App小程序)和波形可视化

文章目录 Recorder-UniCore插件特性集成到项目中调用录音上传录音ASR语音识别 在uniapp中使用Recorder-UniCore插件可以实现跨平台录音功能&#xff0c;uniapp自带的recorderManager接口不支持H5、录音格式和实时回调onFrameRecorded兼容性不好&#xff0c;用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中视频文件【内网穿透】

最近&#xff0c;我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念&#xff0c;而且内容风趣幽默。我觉得它对大家可能会有所帮助&#xff0c;所以我在此分享。点击这里跳转到网站。 文章目录 1.使用环境要求&#xff1a;2.下载群晖videostation&am…...

事件分析应急响应-Server2229(环境+解析)

任务环境说明: 服务器场景:Server2229(开放链接)用户名:root,密码:...

SpringCloud:微服务

文章目录 微服务服务架构演变单例架构&#xff08;集中式架构&#xff09;分布式架构 微服务SpringCloud 微服务 服务架构演变 单例架构&#xff08;集中式架构&#xff09; 单例架构&#xff1a; 将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署 优点&…...

拥抱Guava之集合操作

深入Guava集合操作 在Java开发中&#xff0c;Google Guava库是处理集合的强大工具。起源于Google内部需求&#xff0c;Guava以简洁性、性能优化为理念&#xff0c;提供高效不可变集合和实用工具类。本文深入剖析Guava的核心功能&#xff0c;为开发者呈现集合操作的全新视角&am…...

运算放大器相关知识总结(1)

1、 前言 最近做了一个小项目&#xff0c;这个项目是研发一款阻抗测量仪。这个阻抗测量仪可以测量人体在不同频率下的生物电阻抗&#xff0c;该设备的核心是模拟电路&#xff0c;技术难点是减小模拟电路噪声。该项目前前忙了2个多月&#xff0c;借着研发这个项目的机会把自己掌…...

ZMQ_REQ\REP模式

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

机器人跟踪性能量化指标

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

【GitHub项目推荐--开源的坦克大战】【转载】

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

06、Kafka ------ 各个功能的作用解释(ISR 同步副本、非同步副本、自动创建主题、修改主题、删除主题)

目录 CMAK 各个功能的作用解释★ ISR副本 (同步副本&#xff09;★ 非同步副本★ 自动创建主题★ 修改主题★ 删除主题 CMAK 各个功能的作用解释 ★ ISR副本 (同步副本&#xff09; 简单来说 &#xff0c;ISR 副本 就是 Kafka 认为与 领导者副本 同步的副本。 ISR&#xff0…...

Spring Security实现详解

一、WebSecurityConfigurerAdapter 总配置类&#xff1a; 1、介绍&#xff1a;配置类 2、主要方法&#xff1a; &#xff08;1&#xff09;configure&#xff08;HttpSecurity http&#xff09; protected void configure(HttpSecurity http) throws Exception {this.logge…...

⭐Unity LeapMotion与手的相关开发

LeapMotion 官方文档中文翻译帮助手册教程 Hand 一个Hand手对象表示了一个跟踪的手&#xff0c;一个手总是包含5个手指以及相关属性如&#xff1a;Direction,PalmPosition,和Basis(orientation). lamPosition :手掌中心到Leap设备原点以毫米测量的距离 PalmVelocity :手掌移…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

手游刚开服就被攻击怎么办?如何防御DDoS?

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

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

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

全球首个30米分辨率湿地数据集(2000—2022)

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

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

HashMap中的put方法执行流程(流程图)

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