首页 > 解决方案 > co_await 的协程不会在控制台应用程序中同时运行

问题描述

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

当我在 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 特定的,我希望在这里有另一个答案。

谢谢你。

标签: c++-winrtc++-coroutine

解决方案


我认为 g() 的 3 次执行应该同时发生。

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

这意味着当您调用 g() 函数时,co_await 语句将等待 g() 方法中的操作完成,然后再继续。所以行为是正确的。关于更多细节,您可以参考此文档


推荐阅读