`asyncio.run()` 不等待协程完成
Posted
技术标签:
【中文标题】`asyncio.run()` 不等待协程完成【英文标题】:`asyncio.run()` does not wait for coroutine to finish 【发布时间】: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.run
是 loop.run_until_complete
的一个相当简单的包装器。
【参考方案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 中引用的源代码非常简单以上是关于`asyncio.run()` 不等待协程完成的主要内容,如果未能解决你的问题,请参考以下文章
Python asyncio run_coroutine_threadsafe 从不运行协程?