使用预协程 asio 接口时,我可以立即分派异步函数并让它在上下文中完成。
asio::dispatch([](){
// executes immediately
asio::steady_timer t(ctx, 2s);
t.async_wait([](){
// executes in ctx.run()
});
});
ctx.run()
我想用
asio::awaitable
复制这个,但是 dispatch 不支持协程。
asio::dispatch([]() -> asio::awaitable<void> { // can't dispatch coroutine directly
// should execute immediately
asio::steady_timer t(ctx, 2s);
co_await t.async_wait(asio::use_awaitable);
// should execute in ctx.run()
co_return;
});
ctx.run()
另一方面
asio::co_spawn
只是将协程添加到上下文中,并没有立即启动它。
我可以使用
ctx.poll()
/ctx.run_one()
但协程必须是唯一准备执行的,或者至少是第一个。
此代码有多种方式无法执行它建议的/您描述的将执行的操作:
asio::dispatch([](){
// executes immediately
asio::steady_timer t(ctx, 2s);
t.async_wait([](){
// executes in ctx.run()
});
});
ctx.run();
它永远不会等待2秒,因为t
的析构函数会在启动后立即取消
async_await
。
ctx
显然是静态的或全局的,因为它没有被捕获
error_code
变量,它也不会“在 ctx.run() 中执行 [s]” 因为
dispatch
在 lambda 的关联执行器 上调度。这,因为没有其他关联,将默认为
asio::system_executor
.的默认构造实例
参见例如
我认为这也不准确。正如您提到的那样,您提供的代码无效(因为Q. 另一方面,asio::co_spawn 只将协程添加到上下文中,不会立即启动它。
post
不支持协程)。当固定使用
co_spawn
时,我们可以显示它在里面运行
ctx.run()
:
#include <boost/asio.hpp>
#include <iostream>
namespace asio = boost::asio;
using namespace std::chrono_literals;
int main() {
asio::io_context ctx;
asio::co_spawn(
ctx,
[]() -> asio::awaitable<void> {
auto ex = co_await asio::this_coro::executor;
asio::steady_timer t(ex, 2s);
co_await t.async_wait(asio::use_awaitable);
std::cout << "inside ctx.run()" << std::endl;
// co_return;
},
asio::detached);
std::cout << "before ctx.run()" << std::endl;
ctx.run();
std::cout << "after ctx.run()" << std::endl;
}
打印我真的认为99%的问题都取决于这些错误的前提,所以我在阐述之前等待你的反应。