亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Qt使用QtConcurrent::run實現(xiàn)異步等待和同步調(diào)用

 更新時間:2025年09月18日 10:48:49   作者:__ocean  
Qt使用QtConcurrent::run實現(xiàn)C#中類似async await的用法,雖不如C#的async/await靈活,但可滿足業(yè)務(wù)需求并提升代碼可讀性,下面就來詳細(xì)的介紹一下QtConcurrent::run實現(xiàn)異步等待和同步調(diào)用

在使用Qt進行開發(fā)時,經(jīng)常需要使用異步方法,不同于C#的async/await,Qt中提供了QtConcurrent::run接口方法可供調(diào)用,習(xí)慣了C#的await,便想著能不能封裝幾個類似的函數(shù)在項目中使用,探索了下,有如下幾個方案

首先定義全局線程池

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

方案一,最簡單的封裝調(diào)用,直接異步調(diào)用,無任何返回結(jié)果,也不會卡住調(diào)用線程:

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

調(diào)用時用法如下:

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

方案二,如果我們想在異步執(zhí)行時,調(diào)用線程同步等待,可封裝如下:

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; // 返回是否正常完成
};

此時,執(zhí)行AwaitCallAsync時,調(diào)用線程會同步等待但并不會卡住線程,為了避免長時間等待,也可以添加超時參數(shù)。

方案三,有時,我們在希望在異步函數(shù)調(diào)用完成后能回到調(diào)用線程繼續(xù)執(zhí)行,那么可以添加QFutureWatcher,監(jiān)控異步函數(shù)的執(zhí)行,然后在QFutureWatcher發(fā)送finished時執(zhí)行另一個函數(shù),如下:

auto CallAsyncWithCallback = [](auto func_async, auto func_callback){
		auto future = QtConcurrent::run(globalThreadPool(), func_async);
		auto watcher = new QFutureWatcher<void>();
		// 連接信號,此處connect會被自動執(zhí)行為Qt::QueuedConnection
		QObject::connect(watcher, &QFutureWatcher<void>::finished, [func_callback, watcher]() mutable { 
				func_callback();
				watcher->deleteLater(); // 完成后自動清理
			});
		watcher->setFuture(future);
	}

上面的connect是在調(diào)用線程中執(zhí)行的,而finished信號是在線程池中子線程中發(fā)出來的,跨線程所以Qt會選擇用Qt::QueuedConnection的方式執(zhí)行Lambda 表達式。

方案四,有時,我們希望回調(diào)函數(shù)在特定線程比如主線程中執(zhí)行,如下:

auto CallAsyncWithUICallback = [](FuncAsync func_async, FuncCallback func_callback_onUI) {
		QtConcurrent::run([func_async, func_callback]() {			
			func_async(); // 在子線程執(zhí)行異步函數(shù)
			
			// 回到主線程執(zhí)行回調(diào)
			QMetaObject::invokeMethod(qApp, [func_callback]() {
				func_callback();
				}, Qt::QueuedConnection);
			});
	}

注意,在調(diào)用invokeMethod時,要顯示指定Qt::QueuedConnection。

總體來說,C#的async await很靈活很強大,Qt雖然不能與之相比,但經(jīng)過簡單的封裝,也能寫出比較靈活或者符合自己業(yè)務(wù)需求而又簡潔好讀的異步代碼。

到此這篇關(guān)于Qt使用QtConcurrent::run實現(xiàn)異步等待和同步調(diào)用的文章就介紹到這了,更多相關(guān)Qt QtConcurrent::run異步等待和同步調(diào)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++中map和set的簡介及使用詳解

    C++中map和set的簡介及使用詳解

    本文主要介紹了C++中map和set的簡介及使用詳解,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C語言實現(xiàn)動態(tài)順序表的示例代碼

    C語言實現(xiàn)動態(tài)順序表的示例代碼

    順序表是用一段物理地址連續(xù)的存儲單元依次存儲數(shù)據(jù)元素的線性結(jié)構(gòu)。順序表一般分為靜態(tài)順序表和動態(tài)順序表,本文主要和大家介紹的是動態(tài)順序表的實現(xiàn),需要的可以參考一下
    2022-10-10
  • C++歸并排序代碼實現(xiàn)示例代碼

    C++歸并排序代碼實現(xiàn)示例代碼

    歸并排序?qū)⒋判驍?shù)組分成兩個子數(shù)組,分別對這兩個子數(shù)組進行排序,然后將排序好的子數(shù)組合并,得到排序后的數(shù)組,這篇文章主要介紹了C++歸并排序代碼實現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2025-08-08
  • C++程序內(nèi)存棧區(qū)與堆區(qū)模型案例分析

    C++程序內(nèi)存棧區(qū)與堆區(qū)模型案例分析

    一直以來總是對這個問題的認(rèn)識比較朦朧,我相信很多朋友也是這樣的,總是聽到內(nèi)存一會在棧上分配,一會又在堆上分配,那么它們之間到底是怎么的區(qū)別呢,讓我們一起來看看
    2022-03-03
  • C++ Boost Tokenizer使用詳細(xì)講解

    C++ Boost Tokenizer使用詳細(xì)講解

    Boost是為C++語言標(biāo)準(zhǔn)庫提供擴展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴展的一些C++程序庫的總稱
    2022-11-11
  • C語言數(shù)據(jù)結(jié)構(gòu)與算法之排序總結(jié)(二)

    C語言數(shù)據(jù)結(jié)構(gòu)與算法之排序總結(jié)(二)

    這篇文章住要介紹的是選擇類排序中的簡單、樹形和堆排序,歸并排序、分配類排序的基數(shù)排序,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2021-12-12
  • C語言goto語句簡單使用詳解

    C語言goto語句簡單使用詳解

    C語言中提供了可以隨意濫用的 goto語句和標(biāo)記跳轉(zhuǎn)的標(biāo)號,本文主要介紹了C語言goto語句簡單使用詳解,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C++中Pimpl的慣用法詳解

    C++中Pimpl的慣用法詳解

    Pimpl(Pointer?to?Implementation)是一種常見的?C++?設(shè)計模式,用于隱藏類的實現(xiàn)細(xì)節(jié),本文將通過一個較為復(fù)雜的例子,展示如何使用智能指針來實現(xiàn)?Pimpl?慣用法,需要的可以參考下
    2023-09-09
  • 詳解VS2019使用scanf()函數(shù)報錯的解決方法

    詳解VS2019使用scanf()函數(shù)報錯的解決方法

    本文主要介紹了詳解VS2019使用scanf()函數(shù)報錯的解決方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C語言詳解如何實現(xiàn)帶頭雙向循環(huán)鏈表

    C語言詳解如何實現(xiàn)帶頭雙向循環(huán)鏈表

    帶頭雙向循環(huán)鏈表:結(jié)構(gòu)最復(fù)雜,一般用在單獨存儲數(shù)據(jù)。實際中使用的鏈表數(shù)據(jù)結(jié)構(gòu),都是帶頭雙向循環(huán)鏈表。另外這個結(jié)構(gòu)雖然結(jié)構(gòu)復(fù)雜,但是使用代碼實現(xiàn)以后會發(fā)現(xiàn)結(jié)構(gòu)會帶來很多優(yōu)勢,實現(xiàn)反而簡單
    2022-04-04

最新評論