You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Task Group的任务内部检测自身是否被取消?

如何在asyncio TaskGroup的任务内部检测自身被取消并执行清理?

根据asyncio TaskGroup的特性:组内任意任务抛出异常时,其余运行中的任务会被自动取消。但如果部分任务需要在被取消时执行清理操作,该怎么在任务内部检测到取消事件?

比如下面的代码,原本预期被取消的任务会触发异常并执行清理,但实际运行后并没有看到清理日志:

import asyncio

class TerminateTaskGroup(Exception):
    """用于终止TaskGroup的异常"""

async def task_that_needs_to_cleanup_on_cancellation():
    try:
        await asyncio.sleep(10)
    except Exception:
        print('捕获到异常,执行清理...')


async def err_producing_task():
    await asyncio.sleep(1)
    raise TerminateTaskGroup()


async def main():
    try:
        async with asyncio.TaskGroup() as tg:
            tg.create_task(task_that_needs_to_cleanup_on_cancellation())
            tg.create_task(err_producing_task())
    except* TerminateTaskGroup:
        print('main() 处理终止逻辑')

asyncio.run(main())

执行结果:

$ python3 script.py 
main() 处理终止逻辑

问题原因

你代码里用except Exception:捕获异常,但**asyncio.CancelledError并不属于Exception的子类**——它是专门用于标识任务被取消的异常,继承自BaseException,所以无法被Exception的捕获语句命中。

解决方法

要检测任务被取消,需要显式捕获asyncio.CancelledError,或者使用except BaseException:(不推荐,除非你需要处理所有类型的基础异常)。修改后的任务函数如下:

import asyncio

class TerminateTaskGroup(Exception):
    """用于终止TaskGroup的异常"""

async def task_that_needs_to_cleanup_on_cancellation():
    try:
        await asyncio.sleep(10)
    except asyncio.CancelledError:
        print('任务被取消,执行清理操作...')
        # 若需要让TaskGroup正确感知任务取消状态,建议重新抛出该异常
        raise
    except Exception:
        print('捕获到普通异常,执行清理...')


async def err_producing_task():
    await asyncio.sleep(1)
    raise TerminateTaskGroup()


async def main():
    try:
        async with asyncio.TaskGroup() as tg:
            tg.create_task(task_that_needs_to_cleanup_on_cancellation())
            tg.create_task(err_producing_task())
    except* TerminateTaskGroup:
        print('main() 处理终止逻辑')

asyncio.run(main())

执行结果:

$ python3 script.py 
任务被取消,执行清理操作...
main() 处理终止逻辑

额外注意事项

  • 如果清理操作是异步的,记得用await调用对应的异步清理函数
  • 捕获CancelledError后,若不需要保留任务运行,建议重新抛出该异常,确保TaskGroup能正确处理任务的终止状态
  • 避免滥用except BaseException:,否则会意外捕获到SystemExit、KeyboardInterrupt等系统级异常,导致程序无法正常退出

内容的提问来源于stack exchange,提问作者laur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:52:33