Synchronously Waiting for a Task to Complete
Learn to implement sync_wait() for asynchronous C++ tasks by using SyncWaitTask and coroutines.
We'll cover the following...
An important aspect of the Task
type is that whatever invokes a coroutine that returns a Task
must co_await
on it and is also a coroutine. This creates a chain of coroutines (continuations). For example, assume we have a coroutine like this:
Task<void> async_func() { // A coroutineco_await some_func();}
Then, it’s not possible to use it in the following way:
void f() {co_await async_func(); // Error}
Once we call an asynchronous function that returns a Task
, we need to co_await
on it, or nothing will happen. This is also the reason why we declare Task
to be nodiscard:
so that it generates a compilation warning if the return value is ignored, like this:
void g() {async_func(); // Warning: Does nothing}
The forced chaining of coroutines has the interesting effect that we finally get to the main()
function of the program, which the C++ standard says is not allowed to be a coroutine. This needs to be addressed somehow, and the proposed solution is to provide at least one function that synchronously waits on the asynchronous chains to complete. For example, the CppCoro library includes the function sync_wait()
, which breaks the chain of coroutines, making it possible for an ordinary function to use coroutines.
Unfortunately, implementing sync_wait()
is rather complicated, but to at least make it possible to ...