You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为MyFuture类实现Awaiter以在Asio中搭配CoroutineTS使用?

解决方案

方法1:扩展boost::asio::experimental::awaitable的promise_type添加await_transform重载

Boost.Asio的awaitable通过promise_type的await_transform方法处理co_await操作,我们可以为其添加针对my_future的重载,将自定义future转换为适配Asio协程的awaiter。

步骤与示例代码:

#include <boost/asio/experimental/awaitable.hpp>
#include <boost/asio/io_service.hpp>

// 假设自定义my_future的基础实现
template<typename T>
class my_future {
public:
    using result_type = T;

    // 假设my_future支持设置完成回调
    template<typename CompletionHandler>
    void then(CompletionHandler&& handler) {
        // 实际逻辑:当future完成时调用handler传递结果
    }

    bool is_ready() const noexcept {
        // 返回future是否已完成的状态
        return false;
    }

    T get() {
        // 返回future的结果
        return T{};
    }
};

// 为awaitable的promise_type添加await_transform重载
namespace boost::asio::experimental {
    template<typename T, typename Executor>
    auto await_transform(promise_type<Executor>& p, my_future<T>&& f) {
        struct awaiter {
            my_future<T> future_;
            boost::asio::io_service& io_;

            awaiter(my_future<T>&& f, boost::asio::io_service& io)
                : future_(std::move(f)), io_(io) {}

            bool await_ready() const noexcept {
                return future_.is_ready();
            }

            void await_suspend(std::coroutine_handle<> h) {
                // 将协程恢复操作投递到io_service队列
                future_.then([this, h](T result) {
                    auto& promise = *static_cast<promise_type<Executor>*>(h.promise());
                    promise.set_value(std::move(result));
                    io_.post([h]() { h.resume(); });
                });
            }

            T await_resume() {
                return future_.get();
            }
        };

        return awaiter(std::move(f), p.get_executor().context());
    }
}

方法2:直接为my_future添加co_await重载,适配Asio协程上下文

在my_future类中直接定义operator co_await,返回能兼容Asioawaitable协程的awaiter,利用当前协程的io_service投递恢复操作。

示例代码:

#include <boost/asio/experimental/awaitable.hpp>
#include <boost/asio/io_service.hpp>

template<typename T>
class my_future {
public:
    using result_type = T;

    template<typename CompletionHandler>
    void then(CompletionHandler&& handler) {
        // 实际逻辑:当future完成时调用handler传递结果
    }

    bool is_ready() const noexcept {
        return false;
    }

    T get() {
        return T{};
    }

    // 适配Asio awaitable协程的co_await重载
    template<typename Executor>
    auto operator co_await(boost::asio::experimental::promise_type<Executor>& promise) {
        struct awaiter {
            my_future<T> future_;
            boost::asio::io_service& io_;

            awaiter(my_future<T>&& f, boost::asio::io_service& io)
                : future_(std::move(f)), io_(io) {}

            bool await_ready() const noexcept {
                return future_.is_ready();
            }

            void await_suspend(std::coroutine_handle<> h) {
                future_.then([this, h](T result) {
                    auto& p = *static_cast<boost::asio::experimental::promise_type<Executor>*>(h.promise());
                    p.set_value(std::move(result));
                    io_.post([h]() { h.resume(); });
                });
            }

            T await_resume() {
                return future_.get();
            }
        };

        return awaiter(std::move(*this), promise.get_executor().context());
    }
};

协程启动与注意事项

  • 确保my_future的then方法能正确异步触发回调,这是awaiter工作的核心基础。
  • Boost.Asio 1.66版本的experimental::awaitableAPI存在版本特性,需严格匹配用法。
  • 协程需通过co_spawn关联io_service启动:
boost::asio::io_service io;

auto my_coroutine() -> boost::asio::experimental::awaitable<int> {
    my_future<int> f; // 创建自定义future实例
    int result = co_await f;
    co_return result;
}

// 启动协程并处理异常
boost::asio::experimental::co_spawn(io, my_coroutine(), [](std::exception_ptr e) {
    if (e) std::rethrow_exception(e);
});

io.run();

内容的提问来源于stack exchange,提问作者mouse_00

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 16:22:53