Asyncio.sleep 导致脚本立即结束

Asyncio.sleep causes script to End Immediately

在我下面的简单 asyncio Python 程序中,bar_loop 应该 运行 连续 运行 循环之间有 1 秒的延迟。

事情 运行 当我们只是

    async def bar_loop(self):
        while True:
            print('bar')

但是,当我们添加一个asyncio.sleep(1)时,循环将结束而不是循环。

    async def bar_loop(self):
        while True:
            print('bar')
            await asyncio.sleep(1)

为什么 asyncio.sleep() 导致 bar_loop 立即退出?我们如何让它以 1 秒的延迟循环?

完整示例:

import asyncio
from typing import Optional

class Foo:
    def __init__(self):
        self.bar_loop_task: Optional[asyncio.Task] = None
        
    async def start(self):
        self.bar_loop_task = asyncio.create_task(self.bar_loop())

    async def stop(self):
        if self.bar_loop_task is not None:
            self.bar_loop_task.cancel()

    async def bar_loop(self):
        while True:
            print('bar')
            await asyncio.sleep(1)

if __name__ == '__main__':
    try:
        foo = Foo()
        asyncio.run(foo.start())
    except KeyboardInterrupt:
        asyncio.run(foo.stop())

在 Ubuntu 20.04.

上使用 Python 3.9.5

此行为与调用 asyncio.sleep 无关,但与创建任务但不执行任何其他操作的预期行为有关。 任务将在 asyncio 循环中并行 运行,而其他仅使用协程和 await 表达式的代码可以被认为是线性模式中的 运行 - 然而,因为它们“不碍事”的 - 让我们称之为“可见的执行路径”,它们也不会阻止该流程。

在这种情况下,您的程序只是到达了 start 方法的末尾,没有任何东西被“等待”,asyncio 循环只是完成了它的执行。

如果您没有 运行 与 bar_loop 并行的明确代码,请等待任务。将您的 start 方法更改为:

async def start(self):
    self.bar_loop_task = asyncio.create_task(self.bar_loop())
    try:
        await self.bar_loop_task
    except XXX:
        # handle excptions that might have taken place inside the task