windows C++-高级并发和异步(三)
深入了解 winrt::resume_foreground(下)
调用 winrt::resume_foreground 时会始终先排队,然后展开堆栈。 也可选择设置恢复优先级。
winrt::fire_and_forget RunAsync(DispatcherQueue queue)
{...co_await winrt::resume_foreground(queue, DispatcherQueuePriority::High);...
}
或者,使用默认的排队顺序。
...
#include <winrt/Windows.System.h>
using namespace Windows::System;
...
winrt::fire_and_forget RunAsync(DispatcherQueue queue)
{...co_await queue;...
}
如上所示,请确保包含要 co_await 的类型的命名空间的投影标头。 例如 Windows::UI::Core::CoreDispatcher、Windows::System::DispatcherQueue 或 Microsoft::UI::Dispatching::DispatcherQueue。
或者,检测队列关闭情况并对其进行适当处理,如以下示例所示。
winrt::fire_and_forget RunAsync(DispatcherQueue queue)
{...if (co_await queue){... // Resume on dispatcher thread.}else{... // Still on calling thread.}
}
co_await 表达式返回 true,表明会在调度程序线程上进行恢复。 换而言之,该排队操作是成功的。 与之相反的是返回 false,这表明执行仍保留在调用线程上,因为队列的控制器关闭,再也不能处理队列请求。
因此,在将 C++/WinRT 与协同程序配合使用的情况下,尤其是在进行一些传统的 Petzold 样式桌面应用程序开发的情况下,你拥有很大的控制权限。
取消异步操作和取消回调
使用 Windows 运行时的异步编程功能可以取消正在进行的异步操作或运算。 以下示例调用 StorageFolder::GetFilesAsync 来检索可能较大的文件集合,并将生成的异步操作对象存储在数据成员中。 用户可以选择取消该操作。
// MainPage.xaml
...
<Button x:Name="workButton" Click="OnWork">Work</Button>
<Button x:Name="cancelButton" Click="OnCancel">Cancel</Button>
...// MainPage.h
...
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Storage.Search.h>using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Storage;
using namespace Windows::Storage::Search;
using namespace Windows::UI::Xaml;
...
struct MainPage : MainPageT<MainPage>
{MainPage(){InitializeComponent();}IAsyncAction OnWork(IInspectable /* sender */, RoutedEventArgs /* args */){workButton().Content(winrt::box_value(L"Working..."));// Enable the Pictures Library capability in the app manifest file.StorageFolder picturesLibrary{ KnownFolders::PicturesLibrary() };m_async = picturesLibrary.GetFilesAsync(CommonFileQuery::OrderByDate, 0, 1000);IVectorView<StorageFile> filesInFolder{ co_await m_async };workButton().Content(box_value(L"Done!"));// Process the files in some way.}void OnCancel(IInspectable const& /* sender */, RoutedEventArgs const& /* args */){if (m_async.Status() != AsyncStatus::Completed){m_async.Cancel();workButton().Content(winrt::box_value(L"Canceled"));}}private:IAsyncOperation<::IVectorView<StorageFile>> m_async;
};
...
让我们通过一个简单的示例开始了解取消的实现端。
// main.cpp
#include <iostream>
#include <winrt/Windows.Foundation.h>using namespace winrt;
using namespace Windows::Foundation;
using namespace std::chrono_literals;IAsyncAction ImplicitCancelationAsync()
{while (true){std::cout << "ImplicitCancelationAsync: do some work for 1 second" << std::endl;co_await 1s;}
}IAsyncAction MainCoroutineAsync()
{auto implicit_cancelation{ ImplicitCancelationAsync() };co_await 3s;implicit_cancelation.Cancel();
}int main()
{winrt::init_apartment();MainCoroutineAsync().get();
}
如果运行上述示例,则你会看到,ImplicitCancellationAsync 在三秒钟内每秒输出一条消息,然后,它会由于执行了取消操作而自动终止。 之所以此行为是可行的,是因为在遇到 co_await 表达式时,协同例程会检查它是否已取消。 如果已取消,则它会短路掉,否则它会像正常情况下一样暂停。
当然,取消也可以在协同例程暂停时发生。 仅当协同例程恢复或者遇到另一个 co_await 时,它才会检查取消状态。 问题在于,在响应取消时可能会出现过于粗糙粒度的延迟。
因此,另一种做法是从协同例程内部显式轮询取消。 使用以下列表中的代码更新上述示例。 在此新示例中,ExplicitCancelationAsync 检索 winrt::get_cancellation_token 函数返回的对象,并使用该对象定期检查是否已取消协同例程。 只要尚未取消,协同例程就会无限循环;一旦取消,循环和函数就会正常退出。 结果与前一个示例相同,不过,在此示例中,退出是显式发生的并且受控。
IAsyncAction ExplicitCancelationAsync()
{auto cancelation_token{ co_await winrt::get_cancellation_token() };while (!cancelation_token()){std::cout << "ExplicitCancelationAsync: do some work for 1 second" << std::endl;co_await 1s;}
}IAsyncAction MainCoroutineAsync()
{auto explicit_cancelation{ ExplicitCancelationAsync() };co_await 3s;explicit_cancelation.Cancel();
}
...
等待 winrt::get_cancellation_token 时会使用协同例程代表你生成的 IAsyncAction 信息检索取消标记。 可以针对该标记使用函数调用运算符以查询取消状态,实质上是轮询取消。 如果执行某项计算资源受限的操作,或循环访问大型集合,则这是一种合理的方法。
相关文章:
windows C++-高级并发和异步(三)
深入了解 winrt::resume_foreground(下) 调用 winrt::resume_foreground 时会始终先排队,然后展开堆栈。 也可选择设置恢复优先级。 winrt::fire_and_forget RunAsync(DispatcherQueue queue) {...co_await winrt::resume_foreground(queue, DispatcherQueuePrior…...
河北移动:核心系统数据库成功完成整体迁移 ,实现全栈国产|OceanBase案例
本文作者:移动通信集团河北有限公司架构规划专家,房瑞 项目背景: 中国移动通信集团河北有限公司一直在积极响应国家及集团的号召,以磐舟&磐基云原生为底座,结合国产浏览器、中间件、数据库、操作系统和服务器等&a…...
ZKRollup
目录 ZKRollup 基本概念 运作原理 特点与优势 应用场景 典型项目 ZKRollup ZKRollup,全称为Zero-Knowledge Rollup,是一种基于零知识证明的二层扩容方案(Layer 2)。它旨在通过提高交易处理效率和降低交易成本来扩展区块链网络的能力,尤其是在以太坊等区块链平台上得…...
letcode 分类练习 树的遍历
letcode 分类练习 树的遍历 树的构建递归遍历前序遍历中序遍历后序遍历 迭代遍历前序遍历中序遍历后序遍历 层序遍历层序遍历可以解决的问题107. 二叉树的层序遍历 II199. 二叉树的右视图637. 二叉树的层平均值429. N 叉树的层序遍历515.在每个树行中找最大值116.填充每个节点的…...
redisssion分布式锁
分布式锁的问题 基于setnx的分布式锁实现起来并不复杂,不过却存在一些问题。 锁误删问题 第一个问题就是锁误删问题,目前释放锁的操作是基于DEL,但是在极端情况下会出现问题。 例如,有线程1获取锁成功,并且执行完任…...
嘎嘎嘎拿到去年想要的包
一年多了 继续,把项目收尾吧 好好学前端,外企!react!从0开始,紧迫!加油!...
前奏编曲:如何编写二段式前奏
选好音源 Pianoteq 6 STAGE比较明亮些,适合做前奏的音源 确定和弦进行 比如4536251,每个小节2和弦,每个小节的和弦弹一下 优化和弦进行衔接和织体 二段式不用对和弦进行就近解决的处理,因为前奏前后要形成对比。 前半部分往…...
征服云端:Kubernetes如何让微服务与云原生技术如虎添翼
引言 在这个数字化转型的时代,微服务架构已经成为构建现代应用程序的首选方式。它不仅提高了开发效率,还增强了系统的可扩展性和灵活性。而随着云计算技术的迅猛发展,云原生的概念逐渐深入人心,它代表了一种全新的软件开发方法论…...
开源AI智能名片系统与高级机器学习技术的融合应用:重塑商务交流的未来
摘要:在数字化浪潮的推动下,人工智能(AI)技术,尤其是机器学习领域的快速发展,正深刻改变着各行各业的面貌。开源AI智能名片系统作为这一变革的先锋,通过集成并优化多种高级机器学习技术…...
Java中synchronized的偏向锁是如何减少锁开销的
偏向锁(Biased Locking)是一种优化 Java synchronized 锁的机制,旨在减少在无竞争情况下的锁开销。它通过将锁偏向于单个线程来优化锁的性能。以下是偏向锁减少锁开销的具体方式和原理: 偏向锁的工作原理 锁的初始状态: 当一个对…...
react18 + ts 使用video.js 直播.m3u8格式的视频流
一、安装依赖 我使用的video.js版本是8.17.3,从 Video.js 7.x 开始,HLS 支持被内置到了 Video.js 中所以不需要安装其他依赖 npm i video.js 二、创建VideoPlayer组件 import React, { useEffect, useRef } from react import videojs from video.js …...
使用 onBeforeRouteLeave 组合式函数提升应用的用户体验
title: 使用 onBeforeRouteLeave 组合式函数提升应用的用户体验 date: 2024/8/14 updated: 2024/8/14 author: cmdragon excerpt: 摘要:本文介绍了在Nuxtjs中使用onBeforeRouteLeave组合式函数来提升应用用户体验的方法。onBeforeRouteLeave允许在组件离开当前路…...
uni-app 吸顶方案总结
效果 页面级 uni.pageScrollTo 官方文档:https://uniapp.dcloud.net.cn/api/ui/scroll.html#pagescrollto 原生头部导航 uni.pageScrollTo({selector: #tabs,duration: 300 });(推荐)需要兼容自定义头部导航 <template><view id"demo1" :styl…...
【C#】知识汇总
目录 1 概述1.1 GC(Garbage Collection)1.1.1 为什么需要GC?1.1.2 GC的工作原理工作原理什么是Root?GC算法:Mark-Compact 标记压缩算法GC优化:Generational 分代算法 1.1.3 GC的触发时间1.1.4 如何减少垃圾…...
1、Unity【基础】3D数学
3D数学 文章目录 3D数学1、数学计算公共类Mathf1、Mathf和Math2、区别3、Mathf中的常用方法(一般计算一次)4、Mathf中的常用方法(一般不停计算)练习 A物体跟随B物体移动 2、三角函数1、角度和弧度2、三角函数3、反三角函数练习 物…...
虚拟机ubuntu22的扩容记录
这里lsblk命令能看到, ubuntu逻辑分区只有29G, 但总分区60G,还有接近30G未使用。 rootx:/home/x# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS loop0 7:0 0 63.9M 1 loop /snap/core2…...
Docker 常用配置
Docker 常用配置 1. 配置方法 修改下面位置: Linux:vim /etc/docker/daemon.jsonmacOS:菜单栏图标->Settings->Docker Engine 注意:修改完需要重启Docker Linux:systemctl restart dockermacOS:…...
通过示例了解 .NET Core 中的依赖注入
依赖注入 (DI) 是一种用于实现 IoC(控制反转)的设计模式,可以更好地解耦应用程序内的依赖关系并更轻松地管理它们。.NET Core 内置了对依赖注入的支持,提供了一种有效管理依赖关系的强大方法。 一.什么是依赖注入? 依…...
fetch、FormData上传多张图片
利用fetch方法和FormData对象上传多张图片 formdata()对象可以序列化多张图片 <html><head><meta http-equiv"content-type" content"text/html;charsetUTF-8"/><title>测试fetch和formdata上传多张图片</title></head&…...
C++STL详解(五)——list类的具体实现
一.本次所需实现的三个类及其成员函数接口 链表首先要有结点,因此我们需要实现一个结点类。 链表要有管理结点的结构,因此我们要有list类来管理结点。 链表中还要有迭代器,而迭代器的底层其实是指针。但是我们现有的结点类无法完成迭代器的…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...
GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...
