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

Python asyncio+aiohttp在VS Code调试中残留任务问题排查

问题分析与解答

核心差异:loop.run_until_complete vs asyncio.run

  • asyncio.run每次执行都会创建全新的事件循环,执行完成后自动关闭循环并清理所有关联资源(包括未完成的协程、线程池实例、aiohttp连接池等),所以不会残留前次循环的任务上下文。
  • loop.run_until_complete是复用同一个事件循环,如果get_data()内存在未彻底清理的异步资源(比如未关闭的aiohttp ClientSession、未调用shutdown()的ThreadPoolExecutor、未取消的后台协程),这些资源会在循环中持续累积,反映到调试调用栈上就是残留的任务记录。

VS Code与VSCodium的调试行为差异

两者虽基于相同的debugpy调试核心,但默认配置存在区别:

  • VS Code默认启用了更详细的异步任务追踪和线程上下文记录,会保留更多调试时的调用栈信息,包括未彻底回收的线程池实例、残留协程的上下文,所以你能看到ThreadPoolExecutor栈的堆叠。
  • VSCodium默认调试配置相对精简,未开启深度的异步任务追踪,即使存在资源残留,调试器也不会主动记录并展示这些栈信息,因此看起来没有复现问题。

ThreadPoolExecutor堆叠到20个栈的原因

这并非程序崩溃,而是VS Code调试器的任务追踪上限设置导致的。调试器为避免性能损耗,会限制同时显示的线程/任务栈数量,默认上限通常为20,达到后就不再新增显示,但程序本身的线程池可能仍在正常工作(或已残留)。

解决建议

  • 优先使用asyncio.run替代loop.run_until_complete的循环写法,利用其自动资源管理特性从根源避免残留问题。
  • 若必须复用事件循环,在get_data()内严格管理资源:
    • 用async with ClientSession()管理aiohttp连接,确保每次请求后关闭连接池。
    • 使用ThreadPoolExecutor时,每次用完调用executor.shutdown(wait=True),或用with ThreadPoolExecutor()上下文管理器自动回收。
  • 调整VS Code调试配置:在.vscode/launch.json中添加"asyncio": {"enable": false},关闭异步任务追踪,可减少残留栈的显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 00:22:18