Search code examples
python-asyncioaiohttp

python 3.10.5 asyncio RuntimeError: Event loop is closed


#!/usr/bin/python
# coding=utf-8

import asyncio
import aiohttp

async def http_request(url, session):
    async with session.get(url) as response:
        return await response.text()

async def get_results(tasks):
    result = await asyncio.gather(*tasks)
    return result

async def main():
    async with aiohttp.ClientSession() as session:
        tasks = [http_request(f"https://httpbin.org/delay/1?seq={x}", session) for x in range(3)]
        return await get_results(tasks)

if __name__ == '__main__':
    results = asyncio.run(main(), debug=False)
    for x in results:
        print(x)

I try to use python coroutine module aiohttp to get network request result, but the following exception is thrown:

Exception ignored in: <function _ProactorBasePipeTransport.del at 0x000001B9B9886950> Traceback (most recent call last): File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\asyncio\proactor_events.py", line 116, in del self.close() File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\asyncio\proactor_events.py", line 108, in close self._loop.call_soon(self._call_connection_lost, None) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 750, in call_soon self._check_closed() File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 515, in _check_closed raise RuntimeError('Event loop is closed') RuntimeError: Event loop is closed

python version is 3.10.5 aiohttp version 3.8.1

how can i solve it? please help me


Solution

  • aiohttp documentation describes this situation in graceful-shutdown. Inserting the following (on windows) clears the error for me.

    async def main():
        async with aiohttp.ClientSession() as session:
            tasks = [http_request(f"https://httpbin.org/delay/1?seq={x}", session) for x in range(3)]
            res = await get_results(tasks)
        await asyncio.sleep(1.0)
        return res
    
    if __name__ == '__main__':
        results = asyncio.run(main())
        for x in results:
            print(x)
    

    Alternatively use the last of the solutions posted Issue #1925. Although I accept these messages are warnings - not debug messages - and ignore them. Simpler.

    async def main():
        async with aiohttp.ClientSession() as session:
            tasks = [http_request(f"https://httpbin.org/delay/1?seq={x}", session) for x in range(3)]
            for x in await get_results(tasks):
                print(x)
            ce = create_aiohttp_closed_event(session)
        await ce.wait()
    
    if __name__ == '__main__':
        results = asyncio.run(main())