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

为何asyncio.gather()在单个任务失败时不取消待处理任务?

解决asyncio.gather异常时未取消剩余协程的问题

问题原因

默认情况下,asyncio.gather会等待所有传入的协程/任务完成,哪怕其中某个抛出异常。它只会在所有任务结束后,抛出第一个遇到的异常,不会主动取消其他正在运行的任务。

解决方案

有两种常见方式实现“某个任务异常时取消剩余任务”的需求:

方式1:手动创建Task并在捕获异常后取消所有任务

先把协程包装成asyncio.Task对象,这样可以在捕获异常时主动取消所有未完成的任务:

import asyncio

async def worker(id):
    await asyncio.sleep(1)
    if id == 2:
        raise ValueError("Failing task")
    return id

async def main():
    # 先创建Task对象,而非直接传协程
    tasks = [asyncio.create_task(worker(i)) for i in range(5)]
    try:
        await asyncio.gather(*tasks)
    except Exception as e:
        print("Error:", e)
        # 取消所有未完成的任务
        for task in tasks:
            if not task.done():
                task.cancel()
        # 等待取消完成(避免程序退出警告)
        await asyncio.gather(*tasks, return_exceptions=True)

asyncio.run(main())

方式2:使用asyncio.wait配合return_when参数

asyncio.wait可以设置return_when=FIRST_EXCEPTION,这样一旦有任务抛出异常就立即返回,此时可取消剩余任务:

import asyncio

async def worker(id):
    await asyncio.sleep(1)
    if id == 2:
        raise ValueError("Failing task")
    return id

async def main():
    tasks = [asyncio.create_task(worker(i)) for i in range(5)]
    done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION)
    
    # 检查异常任务
    for task in done:
        try:
            task.result()
        except Exception as e:
            print("Error:", e)
            # 取消所有待完成任务
            for p in pending:
                p.cancel()
            # 等待取消完成
            await asyncio.gather(*pending, return_exceptions=True)
            return
    
    # 所有任务正常完成时收集结果
    results = [task.result() for task in done]
    print("Results:", results)

asyncio.run(main())

补充说明

  • 如果使用asyncio.gather(return_exceptions=True),所有异常会被当作返回值返回,不会抛出,此时也不会取消其他任务,适合需要收集所有结果(包括异常)的场景,但不符合“异常时取消剩余任务”的需求。
  • 手动取消任务后,最好用带return_exceptions=True的gather等待任务完成,避免程序退出时出现未完成任务的警告。

内容的提问来源于stack exchange,提问作者Ritu Raj Aazad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 22:32:32