在Qt项目中使用QtConcurrent::run,实现异步等待和同步调用

在使用Qt进行开发时,经常需要使用异步方法,不同于C#的async/await,Qt中提供了QtConcurrent::run接口方法可供调用,习惯了C#的await,便想着能不能封装几个类似的函数在项目中使用,探索了下,有如下几个方案

首先定义全局线程池

	inline QThreadPool* globalThreadPool() {static QThreadPool* pool = []() {QThreadPool* p = new QThreadPool;p->setMaxThreadCount(QThread::idealThreadCount());return p;}();return pool;}

方案一,最简单的封装调用,直接异步调用,无任何返回结果,也不会卡住调用线程:

	auto CallAsync = [](auto func){QtConcurrent::run(globalThreadPool(), func);};

调用时用法如下:

CallAsync([](){// do something in theadpool...
});

方案二,如果我们想在异步执行时,调用线程同步等待,可封装如下:

auto AwaitCallAsync = [](auto func, int timeoutSeconds = 5) -> bool
{        QFuture<void> future = QtConcurrent::run(globalThreadPool(), func);// 使用智能指针管理对象生命周期auto watcher = std::make_shared<QFutureWatcher<void>>();auto loop = std::make_shared<QEventLoop>();auto timer = std::make_shared<QTimer>();bool timedOut = false;    if (timeoutSeconds > 0) {timer->setInterval(timeoutSeconds * 1000);timer->setSingleShot(true);QObject::connect(timer.get(), &QTimer::timeout, [&timedOut, loop]() {timedOut = true;loop->quit();});timer->start();}    QObject::connect(watcher.get(), &QFutureWatcher<void>::finished, loop.get(), &QEventLoop::quit);watcher->setFuture(future);    loop->exec();// 清理资源if (!timedOut && timeoutSeconds > 0) {timer->stop();}    return !timedOut; // 返回是否正常完成
};

此时,执行AwaitCallAsync时,调用线程会同步等待但并不会卡住线程,为了避免长时间等待,也可以添加超时参数。

方案三,有时,我们在希望在异步函数调用完成后能回到调用线程继续执行,那么可以添加QFutureWatcher,监控异步函数的执行,然后在QFutureWatcher发送finished时执行另一个函数,如下:

auto CallAsyncWithCallback = [](auto func_async, auto func_callback){auto future = QtConcurrent::run(globalThreadPool(), func_async);auto watcher = new QFutureWatcher<void>();// 连接信号,此处connect会被自动执行为Qt::QueuedConnectionQObject::connect(watcher, &QFutureWatcher<void>::finished, [func_callback, watcher]() mutable { func_callback();watcher->deleteLater(); // 完成后自动清理});watcher->setFuture(future);}

上面的connect是在调用线程中执行的,而finished信号是在线程池中子线程中发出来的,跨线程所以Qt会选择用Qt::QueuedConnection的方式执行Lambda 表达式。

方案四,有时,我们希望回调函数在特定线程比如主线程中执行,如下:

auto CallAsyncWithUICallback = [](FuncAsync func_async, FuncCallback func_callback_onUI) {QtConcurrent::run([func_async, func_callback]() {			func_async(); // 在子线程执行异步函数// 回到主线程执行回调QMetaObject::invokeMethod(qApp, [func_callback]() {func_callback();}, Qt::QueuedConnection);});}

注意,在调用invokeMethod时,要显示指定Qt::QueuedConnection。

总体来说,C#的async await很灵活很强大,Qt虽然不能与之相比,但经过简单的封装,也能写出比较灵活或者符合自己业务需求而又简洁好读的异步代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/98163.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/98163.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频分类 pytorchvideo

目录 1. 速度 vs 精度分析 mvit: r2plus1d_r50 推理代码&#xff1a; x3d_xs推理代码&#xff1a; R(21)D X3D&#xff08;轻量级&#xff0c;速度快&#xff09; I3D&#xff08;经典 3D CNN&#xff09; 替换分类层&#xff08;适配你的任务&#xff09; https://gith…

OpenTiny NEXT 内核新生:生成式UI × MCP,重塑前端交互新范式!

近期&#xff0c;我们推出 OpenTiny NEXT —— OpenTiny的下一代企业级前端智能开发解决方案。这不仅是一次技术升级&#xff0c;更是一场用户交互范式的变革&#xff1a;从传统的人机交互升级成为人机交互范式和智能体交互范式的融合。我们坚信&#xff0c;每一个企业应用都值…

深度神经网络1——梯度问题+标签数不够问题

要解决一个复杂问题&#xff0c;可能要训练更深的神经网络&#xff0c;可能会10层及以上&#xff0c;每层包含数百个神经元&#xff0c;成千上万个连接。这样大的神经网络在训练的时候可能会遇到以下问题&#xff1a;这样在进行反向传播的时候&#xff0c;随着层数越来越低会遇…

(笔记)内存文件映射mmap

内存文件映射是一种将文件内容映射到进程的虚拟地址空间的技术&#xff0c;使得文件可以被视为内存的一部分&#xff0c;从而允许程序直接对这部分内存进行读写操作&#xff0c;而无需传统的文件 I/O 调用。这种方法不仅简化了文件操作&#xff0c;还提高了处理效率。 在Linux…

Golang中的NaN(Not a Number)

Golang中的NaN&#xff08;Not a Number&#xff09; 在Go语言中&#xff0c;NaN是浮点数&#xff08;特别是float32和float64&#xff09;中的一个特殊值&#xff0c;表示未定义或不可表示的数值。 go中&#xff0c;除数为0时并不会返回error或者nil&#xff0c;而是返回无穷大…

微软图引擎GraphEngine深度解析:分布式内存计算的技术革命

❝ "在大数据的汪洋中&#xff0c;图引擎就像是一艘能够高速穿越复杂关系网络的超级快船" 引言&#xff1a;当内存遇上图计算的火花 在这个数据爆炸的时代&#xff0c;传统的关系型数据库已经难以应对复杂关系数据的查询挑战。当Facebook的社交网络拥有数十亿用户关…

catkin工程和CMakelist.txt的基本使用

catkin工程和CMakelist.txt的基本使用1.catkin工程和CMakelist.txt的基本使用1. 顶部基本信息2. 编译选项 / C 标准3. 依赖查找&#xff08;catkin 包&#xff09;4. 第三方库查找&#xff08;非 catkin&#xff09;5. 导出包信息&#xff08;catkin_package&#xff09;6. 头文…

uniapp打包前端项目

打包前的准备工作确保项目开发已完成&#xff0c;并且已安装最新版本的HBuilderX。检查项目中所有依赖是否已正确安装&#xff0c;配置文件如manifest.json已根据H5需求进行适配。在HBuilderX中打包在 HBuilderX 中&#xff0c;点击顶部菜单栏的 “发行” -> “网站-H5手机版…

Dify + Bright Data MCP:从实时影音数据到可落地的智能体生产线

一、引言&#xff1a;AI 应用与实时影音数据的融合价值 内容生态近年的“视频化、实时化、社交化”浪潮&#xff0c;将数据获取链路推到了更靠前的位置。真正驱动业务的&#xff0c;不是某一帧漂亮的模型输出&#xff0c;而是“数据—理解—动作”的持续闭环。无论是品牌内容策…

【Linux】make/Makefile工具篇

目录一、自动化构建二、make/Makefile2.1 见识一个简单的make/Makefile2.2 Makefile的基本语法2.3 Makefile的语法细节个人主页<—请点击 Linux专栏<—请点击 一、自动化构建 自动化构建是指通过构建工具&#xff08;如make&#xff09;解析构建脚本&#xff08;如Make…

如何在企业微信上以 HTTPS 方式访问内网 OA/ERP 等系统?

企业微信可以将 ZeroNews 平台上添加的内网应用集成到企业微信的工作台。这样&#xff0c;用户即使在外部网络环境中&#xff0c;也可以通过企业微信访问内网的 OA、ERP 等应用。以下是企业在 Linux 服务器上部署 OA 系统&#xff0c;并通过 ZeroNews 通过互联网访问 OA 系统的…

Windows 11 安装使用 nvm,Node.js、npm多版本管理、切换

Windows 11 安装使用 nvm&#xff0c;Node.js、npm多版本管理、切换 文章目录Windows 11 安装使用 nvm&#xff0c;Node.js、npm多版本管理、切换1. nvm 简介2. 安装、配置 nvm2.1. 卸载现有 Node.js&#xff08;非常重要&#xff01;&#xff09;2.2. 下载 nvm-windows 安装包…

在LazyVim中配置Rust开发环境

要在LazyVim中配置Rust开发环境&#xff0c;包括代码补全、格式化、调试等功能&#xff0c;可以按照以下步骤进行配置&#xff1a; 1. 确保基础环境 首先确保你已经安装了&#xff1a; Rust工具链 (rustup, rustc, cargo)LazyVim已正确安装 # 安装Rust工具链 curl --proto http…

LeetCode热题100--114. 二叉树展开为链表--中等

1. 题目 给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为null 。展开后的单链表应该与二叉树 先序遍历 顺序相同。 示例 …

REST API 设计最佳实践指南 - 如何用 JavaScript、Node.js 和 Express.js 构建 REST API

过去几年里&#xff0c;我创建并使用过很多 API。在此过程中&#xff0c;我遇到过各种好的和坏的实践&#xff0c;也在开发和调用 API 时碰到过不少棘手的问题&#xff0c;但也有很多顺利的时刻。 网上有很多介绍最佳实践的文章&#xff0c;但在我看来&#xff0c;其中不少都缺…

MyCat

文章目录18.1 MySQL 读写分离概述18.1.1 工作原理18.1.2 为什么要读写分离18.1.3 实现方式18.2 什么是 MyCat18.3 MyCat 安装与配置1. 下载与解压2. 创建用户并修改权限3. 目录说明4. Java 环境要求18.4 MyCat 启动与配置1. 配置环境变量2. 配置 hosts&#xff08;多节点集群&a…

使用 Spring Boot 搭建和部署 Kafka 消息队列系统

使用 Spring Boot 搭建和部署 Kafka 消息队列系统 摘要 本文将引导您在 Kafka 上搭建一个消息队列系统&#xff0c;并整合到您的 Spring Boot 项目中。我们将逐步实现这一方案&#xff0c;探讨其中的关键原理&#xff0c;避开可能遇到的坑&#xff0c;并最终将其部署到 Kuberne…

daily notes[45]

文章目录basic knowledgereferencesbasic knowledge the variable in Rust is not changed. let x5; x6;Rust language promotes the concept that immutable variables are safer than variables in other programming language such as python and and are in favour of th…

技术奇点爆发周:2025 年 9 月科技突破全景扫描

技术奇点爆发周&#xff1a;2025 年 9 月科技突破全景扫描当中国 "祖冲之三号" 量子计算机在特定任务上超越经典超级计算机一千万亿倍的算力新闻&#xff0c;与 OpenAI 宣布 100 亿美元定制芯片量产协议的消息在同一周密集爆发时&#xff0c;我们真切感受到了技术革命…

分布式专题——10.3 ShardingSphere实现原理以及内核解析

1 ShardingSphere-JDBC 内核工作原理当往 ShardingSphere 提交一个逻辑SQL后&#xff0c;ShardingSphere 到底做了哪些事情呢&#xff1f;首先要从 ShardingSphere 官方提供的这张整体架构图说起&#xff1a;1.1 配置管控在 SQL 进入 ShardingSphere 内核处理&#xff08;如解析…