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

Win11 Python3.10用aiohttp并发请求报Event loop is closed错误

问题说明

你实现的并发请求逻辑本身可正常工作:4个接口请求全部成功返回、结果正确收集、总耗时符合并发执行预期。抛出的RuntimeError: Event loop is closed属于Windows平台Python异步生态的已知兼容问题,不影响实际业务执行结果。

根本原因

Python 3.8+在Windows系统下默认使用ProactorEventLoop作为异步事件循环实现。当asyncio.run()执行完成、正常关闭事件循环后,aiohttp底层的网络连接管道对象在垃圾回收阶段触发析构逻辑,尝试向已经关闭的事件循环投递资源清理任务,就会触发该异常。异常出现在程序退出前的资源回收阶段,和你的业务请求逻辑无关。

可直接落地的解决方案

方案1:切换事件循环实现(优先推荐,改动最小)

在代码导入asyncio后,立刻将事件循环策略切换为Windows平台兼容的Selector实现,仅需新增1行代码,无任何业务侵入性:

import asyncio
# 新增以下配置即可解决
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
import aiohttp
import time

names = ["rahul"]*4

def get_tasks(session):
    tasks = []
    for name in names:
        tasks.append(asyncio.create_task(session.get(url =f"https://api.agify.io?name={name}", ssl=False)))
    return tasks

async def my_f2():
    result = []
    async with aiohttp.ClientSession() as session:
        tasks = get_tasks(session)
        responses = await asyncio.gather(*tasks,return_exceptions=True)
        for response in responses:
            result.append(await response.json())
    return result

if __name__ == "__main__":
    start = time.time()
    result = asyncio.run(my_f2())
    print(result)
    end = time.time()
    print(f"Total time : {end-start}")

方案2:显式释放HTTP响应资源

原代码中读取响应JSON内容后未显式释放响应对象,会放大资源清理的时序问题,可以通过async with语法主动管理响应对象的生命周期,调整my_f2函数的响应处理段即可:

async def my_f2():
    result = []
    async with aiohttp.ClientSession() as session:
        tasks = get_tasks(session)
        responses = await asyncio.gather(*tasks,return_exceptions=True)
        for response in responses:
            # 显式管理响应对象生命周期,退出上下文时自动释放连接
            async with response:
                result.append(await response.json())
    return result
  • 注意:该方案单独使用时在部分Python版本下仍可能抛出零星异常,和方案1搭配使用可彻底解决问题。

方案3:异常过滤(兜底方案,不推荐优先使用)

如果上述两个方案调整后仍有异常抛出,可以通过自定义异常钩子忽略该特定的无害异常,该方案会全局过滤同类异常,可能掩盖真实的事件循环错误,仅作为兜底使用:

import sys

def silence_event_loop_closed_exception(exc_type, exc_val, exc_tb):
    if issubclass(exc_type, RuntimeError) and str(exc_val) == 'Event loop is closed':
        return
    sys.__excepthook__(exc_type, exc_val, exc_tb)

sys.excepthook = silence_event_loop_closed_exception

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:54:27