...

/

Synchronously Waiting for a Task to Complete

Synchronously Waiting for a Task to Complete

Learn to implement sync_wait() for asynchronous C++ tasks by using SyncWaitTask and coroutines.

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:

Press + to interact
Task<void> async_func() { // A coroutine
co_await some_func();
}

Then, it’s not possible to use it in the following way:

Press + to interact
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:

Press + to interact
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 ...