有什么方法可以真正停止等待的长时间运行的异步任务吗?

问题描述 投票:0回答:1

如果有一个长时间运行的后台任务,

cancel()
方法无法按我的预期工作(根本不起作用)。我找不到真正停止任务的方法,这有可能吗,还是我错过了一些关于
asyncio
工作的事情?

文档说: “

Task.cancel()
不保证任务会被取消。”

但据我了解,这是由于协程处理

CancelledError
异常并抑制取消的可能性,这不是我的情况。

我尝试运行下面的示例代码并永远运行无限循环,

cancel()
不起作用。
我的理解是,在下一个异步事件循环迭代中点击
await asyncio.sleep(1)
应该会触发任务取消,但它没有发生。
我怎样才能让已经等待的
background_task
停下来?

async def background_task():
    while True:
        print('doing something')
        await asyncio.sleep(1)


async def main():
    task = asyncio.create_task(background_task())
    await task
    task.cancel()
    print('Done!')


asyncio.run(main())

输出将是:

doing something
doing something
doing something
doing something
doing something
doing something
...
python task python-asyncio cancellation
1个回答
0
投票

您可以像这样编辑脚本,使其按照您的预期工作:

import asyncio

async def background_task(stop_event):
    while not stop_event.is_set():
        print('doing something')
        await asyncio.sleep(1)

async def main():
    stop_event = asyncio.Event()
    task = asyncio.create_task(background_task(stop_event))
    # Simulate running the task for some time
    await asyncio.sleep(5)
    stop_event.set() # Set the event to stop the background_task
    await task # Await the task to complete
    print('Done!')

asyncio.run(main())

在此修改后的代码中,background_task 协程正在检查 Event 对象 (stop_event)。当设置此事件(stop_event.set())时,background_task 内的循环将由于条件而停止,而 not stop_event.is_set():。这允许任务正常退出,而不必仅仅依赖于任务取消。

希望对您有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.