踩坑实录:Python 异步任务突然不执行,排查了整整一下午

踩坑实录:Python 异步任务突然不执行,排查了整整一下午

今天分享一个真实踩坑经历——asyncio 任务「静默失败」的问题,坑得我一下午没喘上气。

问题现象

项目里有一段异步代码,用来处理一批 HTTP 请求:

import asyncio
import aiohttp

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            return await resp.text()

async def main():
    urls = [
        'https://httpbin.org/delay/2',
        'https://httpbin.org/delay/3',
        'https://httpbin.org/delay/1',
    ]
    tasks = [fetch(url) for url in urls]
    results = await asyncio.gather(tasks)  # ❌ 这里有问题
    print(results)

asyncio.run(main())

运行之后,程序直接退出了,没有任何输出,也没有报错

排查过程

第一反应是「是不是 asyncio.run() 用错了」?换成 loop.run_until_complete(),问题依旧。

try/except,也抓不到异常。

然后用 asyncio.gather(..., return_exceptions=True) 试了一下——终于有输出了:

[TypeError("'list' object is not awaitable"), ...]

原来问题在这里:asyncio.gather() 接收的是「协程对象」,不是「协程对象的列表」

我传的是 tasks(一个 list),但 gather 的签名是 gather(*coros, ...),需要解包。

根因分析

正确写法应该是:

results = await asyncio.gather(*tasks)  # ✅ 解包列表

而我原来写的是:

results = await asyncio.gather(tasks)  # ❌ tasks 是一个 list,不是 coroutine

gathertasks(这个 list)当成一个协程去 await,自然会报 TypeError

但为什么没有报错?因为 asyncio.run() 在捕获到异常后,如果没有被正确 print,异常会被吞掉(特别是在某些 IDE 或运行环境下)。

解决方案

  1. 永远用 return_exceptions=True,至少能看到异常:
results = await asyncio.gather(*tasks, return_exceptions=True)
for r in results:
    if isinstance(r, Exception):
        print(f"任务失败: {r}")
  1. 给每个协程单独加 try/except,别让一个任务炸掉影响全部:
async def safe_fetch(url):
    try:
        return await fetch(url)
    except Exception as e:
        print(f"{url} 失败: {e}")
        return None
  1. 如果用 Python 3.11+,优先用 asyncio.TaskGroup,异常传播更清晰:
async with asyncio.TaskGroup() as tg:
    tasks = [tg.create_task(fetch(url)) for url in urls]
# 这里自动 wait,异常会正确抛出

经验总结

  • asyncio.gather(*coros) 别忘了 * 解包,这是最常见的低级错误
  • 异步代码的异常容易被「吞掉」,调试时一定加 return_exceptions=True
  • Python 3.11 的 TaskGroupgather 更安全,新项目建议直接用
  • 异步 bug 最难查的就是「没报错但结果不对」——遇到这种情况,先怀疑异常被吞了

*你有没有踩过类似的 asyncio 坑?欢迎评论区交流 *

posted @ 2026-06-28 17:38  疯狂的yang  阅读(1)  评论(0)    收藏  举报