【发布时间】:2021-10-31 16:13:39
【问题描述】:
Python 中确保所有并发任务在事件循环结束之前完成的标准方法是什么?这是一个简化的示例:
import asyncio
async def foo(delay):
print("Start foo.") # Eg: Send message
asyncio.create_task(bar(delay))
print("End foo.")
async def bar(delay):
print("Start bar.")
await asyncio.sleep(delay)
print("End bar.") # Eg: Delete message after delay
def main():
asyncio.run(foo(2))
if __name__ == "__main__":
main()
当前输出:
Start foo. # Eg: Send message
End foo.
Start bar.
期望的输出:
Start foo. # Eg: Send message
End foo.
Start bar.
End bar. # Eg: Delete message after delay
我尝试在loop.run_until_complete() 之后运行所有未完成的任务,但这不起作用,因为到那时循环将被终止。我还尝试将 main 函数修改为以下内容:
async def main():
await foo(2)
tasks = asyncio.all_tasks()
if len(tasks) > 0:
await asyncio.wait(tasks)
if __name__ == "__main__":
asyncio.run(main())
输出是正确的,但它永远不会终止,因为协程 main() 是其中一项任务。上面的设置也是discord.py发送消息,一段时间后删除,只是改用loop.run_forever(),所以没有遇到问题。
【问题讨论】:
-
在你的 foo 函数中尝试:
task = [asyncio.create_task(bar(delay))]然后await asyncio.gather(*task, return_exceptions=False)。 -
请注意,这些天您不应该直接与循环交互。使用
asyncio.run而不是手动获取和启动循环。 -
@user56700 我试过了,但它会锁定
foo直到栏完成。bar必须同时运行。一个例子是一个机器人发送一个过期的消息。发送消息的函数应该尽快运行并返回(调用函数只想等到消息发送,而不是等到消息过期)。 -
@MisterMiyagi 谢谢,我用改进的代码编辑了帖子。
标签: python python-3.x python-asyncio