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

2602C++,窗运异步

C++/WinRT是微软为窗口``运行时提供的现代C++17``语言投影.

2018年引入.窗口SDK版本10.0.17134.0(Windows101803).
这里不介绍C++WinRT其他,只介绍它提供的异步能力:

异步操作方法

假设我有个耗时很久的方法,我不希望它阻塞UI线程,那你可这样:

#include<dispatcherqueue.h>#include<winrt/base.h>#include<winrt/Windows.System.h>#include<winrt/Windows.Foundation.h>winrt::Windows::Foundation::IAsyncActionreadImg(){co_awaitwinrt::resume_background();//这里省略了耗时很长的逻辑代码co_awaitwinrt::resume_foreground(dq);}

这里,winrt::Windows::Foundation::IAsyncAction代表一个无结果,无进度异步操作.
除此外,WinRT提供了如下异步操作类型:

类型返回值进度报告使用场景
IAsyncAction简单异步操作
IAsyncActionWithProgress需要进度反馈的操作
IAsyncOperation返回结果异步操作
IAsyncOperationWithProgress返回结果且需进度的操作

如果要在一个方法中使用co_await操作异步逻辑,则你就要按co_await兼容的方法标记该方法,比如返回IAsyncAction类型.
co_await winrt::resume_background()C++/WinRT提供的切换线程助手函数,来从当前线程切换到后台线程(背后有线程池).该操作是非阻塞的.
co_await winrt::resume_foreground(dq)负责从后台线程切换到当前线程.
是不是比C++``标准库里的异步操作要简单的多呢?
dq是什么?

线程任务调度对象

winrt::Windows::System::DispatcherQueue dqC++/WinRT中用来管理线程任务调度核心类,它管理按偏爱级排列任务队列,确保在线程上串行执行任务.
该类型的对象有以下特点:
1,每线程最多有1个DispatcherQueue
2,可向该线程投递异步任务
3,任务按优先级排队执行
4,依赖线程消息循环(MessageLoop)

启动应用时,就创建了管理UI线程的任务队列的该dq对象.

winrt::Windows::System::DispatcherQueue dq;dq{winrt::Windows::System::DispatcherQueue::GetForCurrentThread()}

WinUI3UWP项中,用上述代码就可直接得到dq.

传统的Win32项,必须要提前执行如下逻辑,才能得到dq.(DispatcherQueue不是Win32线程的默认组成部分)

winrt::init_apartment(winrt::apartment_type::single_threaded);DispatcherQueueOptions options{sizeof(DispatcherQueueOptions),DQTYPE_THREAD_CURRENT,DQTAT_COM_STA};staticwinrt::Windows::System::DispatcherQueueController controller{nullptr};autohr=CreateDispatcherQueueController(options,reinterpret_cast<ABI::Windows::System::IDispatcherQueueController**>(winrt::put_abi(controller)));

不要掐死UI线程

假设有如下用来取剪切板内文本的异步代码.

IAsyncOperation<winrt::hstring>Util::getTextFromClipboard(){autoview=Clipboard::GetContent();if(view.Contains(StandardDataFormats::Text())){co_returnco_awaitview.GetTextAsync();}co_returnL"";}

如果如下取剪切板内的文本

autostr=getTextFromClipboard().get();

此时可能会报如下错误:
这是因为:
1,.get()阻塞当前线程等待异步完成
2,异步操作内部需要调度到UI线程执行Clipboard,API(操作剪切板API的要求)
3,但你阻塞了当前UI线程(.get()没返回)
4,无法运行消息循环,无法调度
5,WinRT检测到"该UI线程无法响应",则抛!is_sta_thread.

方案就是不要掐死UI线程

autostrOp=Util::getTextFromClipboard2();strOp.Completed([this](autoconst&sender,autostatus){autostr=sender.GetResults();});

或使用co_await调用getTextFromClipboard方法,来把这段逻辑也包在IAsyncAction方法中.

http://www.jsqmd.com/news/395446/

相关文章:

  • SpringBoot+Vue BS社区物业管理系统平台完整项目源码+SQL脚本+接口文档【Java Web毕设】
  • Java SpringBoot+Vue3+MyBatis 汽车维修预约服务系统系统源码|前后端分离+MySQL数据库
  • Java Web HTML语言环保网站系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】
  • 企业级电影订票及评论网站管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】
  • 【毕业设计】SpringBoot+Vue+MySQL 美妆购物网站平台源码+数据库+论文+部署文档
  • Java SpringBoot+Vue3+MyBatis 美妆购物网站系统源码|前后端分离+MySQL数据库
  • 深入探讨Entity Framework Core中的一对一关系
  • 高效处理大量元素的Chrome扩展开发技巧
  • 解决Catalyst Datastore插入问题
  • Java Web 美妆购物网站系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】
  • SpringBoot+Vue 疫情期间高校人员管理管理平台源码【适合毕设/课设/学习】Java+MySQL
  • Power BI如何助力大数据的精准营销
  • 在春晚“销声匿迹”的歌手平安,早就已经走上了“另一条大道”!
  • Java Web 汽车维修预约服务系统系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】
  • 2026年代理IP采购避坑指南:10家主流服务商实测与选型参考
  • 认知灵活性的提示工程
  • 92岁郭兰英落泪,和董卿真实关系终于揭开,最“亲近”的人原来是她呀!
  • RexUniNLU实战案例:旅游攻略文本中地理位置+情感倾向联合分析
  • 2026年武汉货架供应商如何选?这份深度评测给你答案 - 2026年企业推荐榜
  • translategemma-4b-it商业应用:外贸文档+产品图双模实时翻译系统
  • GDPR数据最小化原则在大数据收集中的落地实践
  • Qwen3-ForcedAligner实战:多语言语音识别与对齐案例
  • Nano-Banana与Matlab集成:科学计算加速方案
  • 金融常识集
  • Qwen3-VL如何应对模糊图像?低光OCR识别部署优化实战指南
  • StructBERT本地化方案:无需网络的中文语义匹配工具体验
  • 中文文本相似度计算不求人:StructBERT快速上手指南
  • 小白也能用的Qwen3-ForcedAligner-0.6B字幕工具
  • Fish-Speech-1.5在教育领域的应用:多语言学习材料制作
  • Qwen2.5-Coder-1.5B代码修复实战:常见问题解决方案