co_await'ed 协程不会 运行 在控制台应用程序中并发

co_await'ed coroutines don't run concurrently in a console application

我不明白我的小代码示例的输出。

当我在 MS C++/WinRT 代码内部调试时,我看到对 WINRT_TrySubmitThreadpoolCallback() 和 WINRT_CreateThreadpoolTimer() 的调用。我认为 g() 的 3 个执行应该同时发生。

此代码:

auto g() -> IAsyncAction {
    Log(L"Entering g()");
    co_await winrt::resume_after(1s);
    Log(L"Exiting g()");
}
auto f() -> IAsyncAction {
    Log(L"Entering f()");
    co_await winrt::resume_background();
    Log(L"First call to g()");
    co_await g();
    Log(L"Second call to g()");
    co_await g();
    Log(L"Third call to g()");
    co_await g();
    Log(L"Exiting f()");
}
auto main() -> int {
    init_apartment();
    f().get();
    return 0;
}

输出以下内容(以线程 ID 为前缀):

24000   Entering f()
13160   First call to g()
13160   Entering g()
13160   Exiting g()
13160   Second call to g()
13160   Entering g()
13160   Exiting g()
13160   Third call to g()
13160   Entering g()
13160   Exiting g()
13160   Exiting f()

它不会同时 运行 g() 实例。不应该吗?

我正在 Slack (Cpplang#coroutines) 上讨论这个问题,很多人都在友好地试图让我理解为什么我的示例代码会这样工作。 Ast 他们的解释不是 C++/WinRT 特定的,我希望在这里有另一个答案。

谢谢。

I think 3 execution of g() should happen concurrently.

C++/WinRT 将 C++ 协程集成到编程模型中,以提供一种协作等待结果的自然方式。您可以通过编写协程来生成自己的 Windows 运行时异步操作。协程是一个与任何其他函数一样的函数,调用者被阻塞直到函数 returns 执行它。您可以使用 co_await 语句协作等待 returns 这些异步操作类型之一的任何函数的结果。

这意味着当你调用g()函数时,co_await语句会等待g()方法中的操作完成后再继续。所以行为是正确的。更详细的可以参考这个document.