达到特定条件后取消异步任务

Cancel asyncio task upon reaching certain condition

如何在达到特定条件时正确关闭 asyncio 无限循环任务?假设我想在函数中的数字达到 20 时取消无限循环:

import asyncio

async def main(numb):
    if numb == 20:
        print('Reached')
        get_loop = asyncio.get_running_loop()
        get_loop.stop()

    print(numb)

async def create_tasks():
    numb = 0 

    while True:
        x = asyncio.create_task(main(numb))
        
        numb += 1
        await x

asyncio.run(create_tasks())

有没有更合适的方法呢?如果我不取消任务异步方式而只是使用“return”,事件循环就会挂起并且永远不会将脚本完成打印到标准输出。

使用现有代码,只需在 main 上引发异常,它将在 await 点重新引发。


import asyncio

class StopTasks(Exception):
    pass

async def main(numb):
    if numb == 20:
        raise StopTasks()

    print(numb)

async def create_tasks():
    numb = 0 

    while True:
        x = asyncio.create_task(main(numb))
        
        numb += 1
        try:
            await x
        except StopTasks:
            break

asyncio.run(create_tasks())

如果您是 运行 并行任务,尽管还有其他方法 - 可能你最好使用 asyncio.wait 并取消未决任务 - 在这种情况下你必须使用全局变量来传达你已经完成 - (它也可能是一个例外)