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

在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://KLDK4OhF.mpLLd.cn
http://yFCztFks.mpLLd.cn
http://vrhRmeMl.mpLLd.cn
http://IIDoCpeF.mpLLd.cn
http://kQq8Wb5U.mpLLd.cn
http://eBpSAC5G.mpLLd.cn
http://CFuhNhKq.mpLLd.cn
http://ZaaoEVKh.mpLLd.cn
http://eNAsfWr6.mpLLd.cn
http://LV2s2RWr.mpLLd.cn
http://hKHwaizD.mpLLd.cn
http://d9saucsM.mpLLd.cn
http://EetGNTVm.mpLLd.cn
http://6MKwie0F.mpLLd.cn
http://SMBvJJxK.mpLLd.cn
http://1vW72XCj.mpLLd.cn
http://6UGSQq2w.mpLLd.cn
http://MVQ9K5x5.mpLLd.cn
http://O67HNZTL.mpLLd.cn
http://AfFC71xA.mpLLd.cn
http://NsOo8g5x.mpLLd.cn
http://cYf9ZucX.mpLLd.cn
http://SqogVVud.mpLLd.cn
http://ehWK1Rdd.mpLLd.cn
http://ckSpQKPH.mpLLd.cn
http://S8htIapA.mpLLd.cn
http://vdZK49VT.mpLLd.cn
http://Okt6VwYC.mpLLd.cn
http://dtWQJcAT.mpLLd.cn
http://ckQO9lU9.mpLLd.cn
http://www.dtcms.com/a/386197.html

相关文章:

  • 经验分享只靠口头传递会带来哪些问题
  • Linux底层-内核数据接口:/proc
  • PEFT+DeepSpeed 1 (微调 分布式 显存优化)
  • Spring Boot 下 Druid 连接池:多维度优化打造卓越性能
  • 提升学术研究能力:从开题构思难题到AI辅助提纲生成
  • spring-kafka的消息拦截器RecordInterceptor
  • VSCode + Python 开发踩坑:虚拟环境不在项目根目录导致包无法识别该怎么办
  • 【MCP】【FastMCP】[特殊字符] 使用 UV 创建 FastMCP 服务完整示例
  • 蓝绿部署(Blue-Green Deployment)介绍(一种用于降低软件发布风险的部署策略)流量切换(金丝雀发布)
  • 羽毛球地板:从专业运动场景到全民健身市场的技术跃迁与产业重构
  • 【实战】预警算法--噪声添加机制
  • Three.js 中如何给 3D 模型添加文字标签?
  • 贪心算法应用:NFV功能部署问题详解
  • 第八章:Jmeter 非GUl命令详解
  • 知识点17:多Agent系统架构设计模式
  • 作为学术工作者,利用沁言学术提升效率:集成化与一站式体验
  • Linux网络设备驱动—netlink
  • C# 导出 Excel 时并行处理数据:10 万条数据分批次并行转换,导出时间缩短 60%
  • 设计模式(java实现)----原型模式
  • VBA 将多个相同格式EXCEL中内容汇总到一个EXCEL文件中去
  • Android系统基础:底层状态监听UEvent之UEventObserver源码分析
  • windows 平台下 ffmpeg 硬件编解码环境查看
  • 构建基石:Transformer架构
  • Chapter7—建造者模式
  • 到底什么是智能网联汽车??第二期——决策与控制
  • 将普通Wpf项目改成Prism项目
  • 微硕WINSOK高性能N沟道场效应管WSD3040DN56,助力汽车中控散热风扇静音长寿命
  • nextjs+shadcn+tailwindcss实现博客中的overview
  • cursor-关于自定义指令的问题处理
  • Vision Transformer (ViT) :Transformer在computer vision领域的应用(四)