Closed wangganglab closed 6 months ago
@marty1885 It seems that variables cannot be captured using =, Because it will be destructed, Do you know why?
int main() {
{
auto ptr = std::make_shared<std::string>("hh");
drogon::async_run([ptr]() -> drogon::AsyncTask {
std::cout << "start co_await test2()" << std::endl;
try {
std::cout << ptr.use_count() << std::endl;
co_await test2();
std::cout << ptr.use_count() << std::endl;
} catch (...) {
std::cout << "异常" << std::endl;
}
std::cout << "end co_await test2()" << std::endl;
co_return;
});
}
}
➜ git:(master) ✗ ./a.out
start co_await test2()
2
test2 start sleep
test2 end sleep
0
end co_await test2()
@nqf May you share the full source code and the compiler you use? I can't tell without knowing that test2
is.
My guess is that you want to use sync_wait
instead of async_run
. async_runc
returns immediately when it needs to wait, which in your case reaches the end of the program. Thus the true execution order is:
std::cout << "start co_await test2()" << std::endl;
std::cout << ptr.use_count() << std::endl;
test2()
test2
suspends the coroutinetest2
got resumed while destructingstd::cout << ptr.use_count() << std::endl
std::cout << "end co_await test2()" << std::endl;
Or put app().run()
at the end of main to keep the event loop running.
Important: sync_wait
accepts a Task<T>
instead of a coroutine function. The syntax is rogon::async_run([ptr]() -> drogon::Task<> {...} ());
The naming is weird. And in most cases you want to use Task insead of AsyncTask. Task<>
is fully async. And AsyncTask
should be named FireAndForget
, it's named that way because of internal C++ details.
Hi, WS clients and controllers does not support coroutines natively now. However, you can wrap a
AsyncTask
within them.Same works for servers