在早期 VS2005 專案中,異步操作(服務調用、複雜解析)需更新 UI,典型流程極其繁瑣:
boost::thread 要求的介面(常用內部類模擬 Lambda);PostMessage 到 UI 窗口;每次遵循此模式都要在多文件間跳轉、增加對象耦合,開發體驗極差,甚至誘導開發者「偷懶」在工作線程直接操作 UI 導致崩潰。
我們期望的理想寫法(參考 C# Task/await 或 Promise 模式):
async([=]() -> DWORD_PTR {
std::string result;
m_impl->user->getCrashResult(begin->first, result);
return CrashResult::GetResultCount(result);
}).then([=](DWORD_PTR result) {
UpdateCrashResult(begin->first.fileId(), (int)result);
});
async 中的 Lambda 在工作線程執行(可阻塞);then 中的 Lambda 在 UI 線程執行(安全更新界面);async 將 Lambda 與 then 行為封裝為任務對象,存入隊列;DWORD_PTR (),返回值自動傳遞給 then;DWORD_PTR(本質是整數/指針)作為通用載體,靈活傳遞結果;BimWorks::GetAsyncAction().Append(...))。// 工作線程內部執行流程
[this]() {
this->result_ = func_(); // 執行用戶任務
GetBWAsyncInvoke().Submit(*this); // 提交回調到 UI 線程
};
Submit 向該窗口 PostMessage,攜帶任務對象指針;then 回調;| 優勢 | 局限與待優化 |
|---|---|
| 極大簡化異步 UI 更新代碼 消除跨文件跳轉與樣板代碼 類型安全的結果傳遞 |
僅適用固定「異步執行→UI回調」模式 缺乏異常處理、取消、超時機制 未利用 VS2010 PPL 庫的 task、並行算法等高級抽象 |
這個初步實現雖然簡陋,但精準解決了高頻場景的痛點。後續可引入 std::future/std::packaged_task(C++11)、PPL task 或成熟的 Boost.Asio/folly::Future 構建更完備的異步框架,支援組合、錯誤傳播、調度控制等企業級需求。