`asyncio.run()` 不等待协程完成

时间:2021-03-20 19:33:19

标签: python python-asyncio

我在 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) 会在继续之前等待协程完成。

1 个答案:

答案 0 :(得分:4)

如果你想等待 create_task 产生的所有任务完成,那么你需要明确地完成它,例如,只需为它们依次 await 或 asyncio 设施,如 { {3}} 或 gather(差异描述为 wait)。否则,它们将在退出主协程时被 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__