在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
英文地址,請注明出處:http://en.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;如解析…