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类来管理结点。 链表中还要有迭代器,而迭代器的底层其实是指针。但是我们现有的结点类无法完成迭代器的…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
