【问题标题】:`asyncio.run()` does not wait for coroutine to finish`asyncio.run()` 不等待协程完成
【发布时间】:2021-03-20 19:33:19
【问题描述】:

我在 Python 3.7.3 中运行此代码

import asyncio

async def fun(time):
    print(f"will wait for {time}")
    await asyncio.sleep(time)
    print(f"done waiting for {time}")

async def async_cenas():
    t1 = asyncio.create_task(fun(1))
    print("after 1")
    t2 = asyncio.create_task(fun(2))
    print("after 2")

def main():
    t1 = asyncio.run(async_cenas())
    print("ok main")
    print(t1)

if __name__ == '__main__':
    main()
    print("finished __name__")

得到这个输出:

after 1
after 2
will wait for 1
will wait for 2
ok main
None
finished __name__

我也期待看到:

done waiting for 1
done waiting for 2

即,为什么期望 asyncio.run(X) 会等待协程完成后再继续。

【问题讨论】:

  • 您的问题是什么? run 等待主协程,然后取消所有其他任务,您可以阅读 implementation
  • 感谢源链接,这有助于@NobbyNobbs
  • @larsks run_until_complete 将遇到完全相同的“问题”,即只等待您告诉它等待的内容。事实上,asyncio.runloop.run_until_complete 的一个相当简单的包装器。

标签: python python-asyncio


【解决方案1】:

如果您想等待由create_task 生成的所有任务完成,那么您需要明确地通过例如await 依次为它们或gather 或@ 等异步设施来完成它987654322@(区别描述here)。否则会在退出主协程时被asyncio.run取消,传递给asyncio.run

例子:

import asyncio

async def fun(time):
    print(f"will wait for {time}")
    await asyncio.sleep(time)
    print(f"done waiting for {time}")

async def async_cenas():
    t1 = asyncio.create_task(fun(1))
    print("after 1")
    t2 = asyncio.create_task(fun(2))
    print("after 2")
    await asyncio.wait({t1, t2}, return_when=asyncio.ALL_COMPLETED)
    # or just
    # await t1
    # await t2

def main():
    t1 = asyncio.run(async_cenas())
    print("ok main")
    print(t1)

if __name__ == '__main__':
    main()
    print("finished __name__")
after 1
after 2
will wait for 1
will wait for 2
done waiting for 1
done waiting for 2
ok main
None
finished __name__

【讨论】:

  • 从这里的文档中我不清楚docs.python.org/3.7/library/…
  • 我可以让它在 main() 函数中等待吗?或者只是在 async_cenas() 中?
  • await 仅在 async def 函数(协程)内有效
  • 文档并不完美,但在 cmets 中引用的源代码非常简单
猜你喜欢
  • 2017-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 2012-04-01
  • 1970-01-01
相关资源
最近更新 更多