如何将C#异步多任务实现代码迁移至C++?
C# Task 异步逻辑迁移到C++的实现方案
你的C#代码核心是并行启动多个异步延迟任务,等待所有任务完成,在C中有两种主流实现方式,分别对应不同的C版本:
一、C++20 协程实现(贴近C# async/await风格)
C++20引入协程特性后,可实现和C#高度相似的异步非阻塞逻辑,以下是对应实现:
首先需要定义基础的task协程返回类型(标准库暂未提供开箱即用的task,需简单封装):
#include <coroutine> #include <future> #include <string> #include <chrono> #include <iostream> template<typename T> struct task { struct promise_type { std::promise<T> promise; auto get_return_object() { return task{std::coroutine_handle<promise_type>::from_promise(*this)}; } auto initial_suspend() { return std::suspend_never{}; } auto final_suspend() noexcept { return std::suspend_never{}; } void return_value(T value) { promise.set_value(std::move(value)); } void unhandled_exception() { promise.set_exception(std::current_exception()); } }; std::coroutine_handle<promise_type> handle; task(std::coroutine_handle<promise_type> h) : handle(h) {} ~task() { handle.destroy(); } std::future<T> get_future() { return handle.promise().promise.get_future(); } }; // 异步延迟等待的可等待对象 struct delay { std::chrono::milliseconds ms; bool await_ready() const noexcept { return ms.count() == 0; } void await_suspend(std::coroutine_handle<> handle) const { std::thread([handle, ms = ms]() { std::this_thread::sleep_for(ms); handle.resume(); }).detach(); } void await_resume() const noexcept {} }; // 对应C#的DoTaskAsync task<std::string> DoTaskAsync(const std::string& name, int timeout) { auto start = std::chrono::steady_clock::now(); std::cout << "Enter " << name << ", " << timeout << std::endl; co_await delay{std::chrono::milliseconds(timeout)}; auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start); std::cout << "Exit " << name << ", " << duration.count() << std::endl; co_return name; } // 对应C#的DoSomethingAsync task<void> DoSomethingAsync() { auto t1 = DoTaskAsync("t2.1", 3000); auto t2 = DoTaskAsync("t2.2", 2000); auto t3 = DoTaskAsync("t2.3", 1000); // 等待所有任务完成,依赖C++20的std::when_all co_await std::when_all(t1.get_future(), t2.get_future(), t3.get_future()); } // 调用示例 int main() { auto task = DoSomethingAsync(); task.get_future().wait(); return 0; }
二、兼容C++11/14/17的实现(基于std::future + std::async)
如果无法使用C++20协程,可通过标准库异步工具实现并行任务等待:
#include <future> #include <string> #include <chrono> #include <iostream> #include <vector> // 对应C#的DoTaskAsync std::string DoTaskAsync(const std::string& name, int timeout) { auto start = std::chrono::steady_clock::now(); std::cout << "Enter " << name << ", " << timeout << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(timeout)); auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start); std::cout << "Exit " << name << ", " << duration.count() << std::endl; return name; } // 自定义实现WhenAll逻辑 void WhenAll(std::vector<std::future<std::string>> futures) { for (auto& f : futures) { f.wait(); } } // 对应C#的DoSomethingAsync void DoSomethingAsync() { auto t1 = std::async(std::launch::async, DoTaskAsync, "t2.1", 3000); auto t2 = std::async(std::launch::async, DoTaskAsync, "t2.2", 2000); auto t3 = std::async(std::launch::async, DoTaskAsync, "t2.3", 1000); WhenAll({std::move(t1), std::move(t2), std::move(t3)}); } // 调用示例 int main() { DoSomethingAsync(); return 0; }
说明
- C++20协程版本更贴近C#的
async/await语义,属于非阻塞异步执行; - 兼容版本通过
std::async启动后台线程,依赖系统线程池实现,需注意线程资源管理; - 两个版本都能实现和原C#代码完全一致的输出效果:三个任务并行启动,按超时时间从短到长依次退出,最后等待所有任务完成。
内容的提问来源于stack exchange,提问作者marcoluca987
相关产品推荐
相关产品推荐

