Runtimeerror event loop is closed windows

When trying to run the asyncio hello world code example given in the docs: import asyncio async def hello_world(): print("Hello World!") loop = asyncio.get_event_loop() # Blocking call which

You have already called loop.close() before you ran that sample piece of code, on the global event loop:

>>> import asyncio
>>> asyncio.get_event_loop().close()
>>> asyncio.get_event_loop().is_closed()
True
>>> asyncio.get_event_loop().run_until_complete(asyncio.sleep(1))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/.../lib/python3.6/asyncio/base_events.py", line 443, in run_until_complete
    self._check_closed()
  File "/.../lib/python3.6/asyncio/base_events.py", line 357, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

You need to create a new loop:

loop = asyncio.new_event_loop()

You can set that as the new global loop with:

asyncio.set_event_loop(asyncio.new_event_loop())

and then just use asyncio.get_event_loop() again.

Alternatively, just restart your Python interpreter, the first time you try to get the global event loop you get a fresh new one, unclosed.

As of Python 3.7, the process of creating, managing, then closing the loop (as well as a few other resources) is handled for you when use asyncio.run(). It should be used instead of loop.run_until_complete(), and there is no need any more to first get or set the loop.

There are so many solutions to this Runtime error on Stack Overflow that don’t work. If you write Python code using asyncio, you either have or most likely will run into this runtime error at some point. I personally came across this error while running asynchronous API requests. When you’re running an async/await function using the asyncio library, you may get a RuntimeError: Event Loop is closed error even after your loop is already done running. This problem may not always affect the functionality of a single script but will affect the functionality of multiple scripts. 

In this post we’ll go over:

  • The asyncio run vs loop.run_until_complete commands
  • The Runtime Error: Event loop is closed Problem
    • Error logs from the asyncio library
  • The Runtime Error: Event loop is closed Solution
    • Editing the Source Code of the asyncio library locally.

Click here for the source code you can copy and paste directly into your program → asyncio Runtime Error: Event Loop is closed Solution

The asyncio Library and run vs loop.run_until_complete

The aforementioned issue can come up when using the asyncio.run() or the loop.run_until_complete() functions. The documentation suggests using run() over run_until_complete() because run() handles the setting and closing of the event loop object. The run() command is actually just a wrapper around the run_until_complete() command. For a more thorough explanation, I suggest reading this guide on run() vs run_until_complete().

Runtime Error: Event Loop is closed Problem

Usually, this error can be fixed by replacing the asyncio.run() command with the command asyncio.new_event_loop().run_until_complete(). However, when used in conjunction with the aiohttp library to make multiple API requests, that alternative will not work. This is due to multiple reasons. First, a TCP connector problem, second an SSL protocol problem, and thirdly an issue with the Proactor transport object. Let’s take a look at what the error logs for this problem may look like prior to the RuntimeError: Event Loop is closed line.

Error Logs from the asyncio Library

Here is what the logs look like for this error:

Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x00000254D4590280>, 25425.812)]']
connector: <aiohttp.connector.TCPConnector object at 0x00000254D4584730>
Fatal error on SSL transport
protocol: <asyncio.sslproto.SSLProtocol object at 0x00000254D459E1C0>
transport: <_ProactorSocketTransport fd=916 read=<_OverlappedFuture cancelled>>
…
AttributeError: 'NoneType' object has no attribute 'send'
Exception ignored in: <function _SSLProtocolTransport.__del__ at 0x00000254D4095E50>
Traceback (most recent call last):
…
RuntimeError: Event loop is closed

Runtime Error: Event Loop is closed Solution

The problem with this error being raised isn’t so much that we can’t run the function. It’s more so we have an error exit code, can’t run multiple functions in sequence, and get yelled at by the command line. The asyncio library not the most stable. So, this error is not too surprising, but you know what is surprising? This error has been around for a while. I found so many solutions on Stack Overflow that don’t work. Theoretically run() should close the event loop gracefully. Gracefully means no errors. Let’s look at how we can change the source code to force a graceful shutdown of the function.

Edit the Source Code of the asyncio Library run Command Locally

How are we going to fix the error? We’re going to wrap a modification around the class for the _ProactorBasePipeTransport’s delete method. This is the method that shuts down the event loop throwing the error. To do this, we’re going to import the wraps annotation from functools and the _ProactorBasePipeTransport from asyncio.proactor_events. Technically we don’t have to import the Proactor class, but we’ll import for ease.

Let’s create our helper function to shut the interpreter up after we’ve already finished our loop. Our function will take one parameter, the function we’re wrapping. We’ll annotate a wrapper function that wraps the passed in function parameter. The inner wrapper function will take itself as an argument, and any number of unnamed and named arguments.

All the wrapper function does is try to execute the function as normal, except when there’s a RuntimeError, it’s not raised. After defining the functions, we’ll edit the __del__ function of the Proactor object and set it to the silenced version. Now the closing of the loop will not raise errors in the console.

"""fix yelling at me error"""
from functools import wraps
 
from asyncio.proactor_events import _ProactorBasePipeTransport
 
def silence_event_loop_closed(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        try:
            return func(self, *args, **kwargs)
        except RuntimeError as e:
            if str(e) != 'Event loop is closed':
                raise
    return wrapper
 
_ProactorBasePipeTransport.__del__ = silence_event_loop_closed(_ProactorBasePipeTransport.__del__)
"""fix yelling at me error end"""

Summary fixing the RuntimeError: Event Loop is closed asyncio Error

The problem we encountered was the program shutdown process raising an error when running asyncio.run() on an async event loop when it shouldn’t have. The solution we implemented doesn’t directly solve the issue of the program not closing all its processes gracefully, but it does protect us from the problem. We directly imported the responsible object and wrote a wrapper around it with the functools Python library. The wrapper function silences the RuntimeError.

Further Reading

  • Python Speech Recognition with SpeechRecognition Library
  • Build Your Own AI Text Summarizer
  • Web Scraping with Python Selenium and Beautiful Soup 4
  • The Best Way to do Named Entity Recognition (NER)
  • How to Send an Email with an Attachment in Python

I run this site to help you and others like you find cool projects and practice software skills. If this is helpful for you and you enjoy your ad free site, please help fund this site by donating below! If you can’t donate right now, please think of us next time.

Make a one-time donation

Your contribution is appreciated.

Donate


Make a monthly donation

Your contribution is appreciated.

Donate monthly


Make a yearly donation

Your contribution is appreciated.

Donate yearly

Yujian Tang

Problem Description

Aiohttp’s getting started entry case is written

import aiohttp
import asyncio


async def main():
    async with aiohttp.ClientSession() as session:
        async with session.get('https://python.org') as response:
            print("Status:", response.status)
            print("Content-type:", response.headers['content-type'])

            html = await response.text()
            print("Body:", html[:15], "...")


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Operation results

Status: 200
Content-type: text/html; charset=utf-8
Body: <!doctype html> ...

It seems that there is no problem, but after Python3.7, it has been improved, and it can be called directly.asyncio.run() Execute the extension program without the operation of the underlying API such as an event loop loop, the above code

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Can be replaced directly

asyncio.run()

There is no problem in Linux and Mac, but running on Windows will report the following error.

Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000001B1FFE978B0>
Traceback (most recent call last):
  File "D:DevToolsPythonlibasyncioproactor_events.py", line 116, in __del__
    self.close()
  File "D:DevToolsPythonlibasyncioproactor_events.py", line 108, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "D:DevToolsPythonlibasynciobase_events.py", line 746, in call_soon
    self._check_closed()
  File "D:DevToolsPythonlibasynciobase_events.py", line 510, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

Cause Analysis

Third-party counterparts like AIOHTTP are dependent on standard library asyncio, and Asyncio has not been good for Windows. After Python 3.8, the event loop on the Windows system is used.ProactorEventLoop (For Windows only) This document describes its defects under Windos:https://docs.python.org/zh-cn/3/library/asyncio-platforms.html#windows 👈

The function of causing an exception is_ProactorBasePipeTransport.__del__ Therefore, AiOHTTP iron is used to use _ProactorBasePiPipTransport, and it is automatically called when the program exits the memory.__del__ method

It is the above series of serial reactions to eventually throw RuntimeError: Event loop is closed

The general extension program does not use _ProactorBasePiPipetransport, so the following code can still run normally

import asyncio


async def main():
    print('Hello...')
    await asyncio.sleep(1)
    print('...World')


asyncio.run(main())

I deliberately wrote a decorator to verify this:

import asyncio
from asyncio.proactor_events import _ProactorBasePipeTransport
from functools import wraps


def explicit_call(func):
    @wraps(func)
    def wrappers(self, *args, **kwargs):
        print('call _ProactorBasePipeTransport.__del__')
        return func(self, *args, **kwargs)

    return wrappers


_ProactorBasePipeTransport.__del__ = explicit_call(_ProactorBasePipeTransport.__del__)


async def main():
    print('Hello...')
    await asyncio.sleep(1)
    print('...World')


asyncio.run(main())

Normal execution, no use _ProactorBasepiPetransport

Hello...
...World
import asyncio
from asyncio.proactor_events import _ProactorBasePipeTransport
from functools import wraps

import aiohttp


async def main():
    async with aiohttp.ClientSession() as session:
        async with session.get('https://www.baidu.com') as response:
            print("Status:", response.status)
            print("Content-type:", response.headers['content-type'])

            html = await response.text()
            print("Body:", html[:15], "...")


def explicit_call(func):
    @wraps(func)
    def wrappers(self, *args, **kwargs):
        print('call _ProactorBasePipeTransport.__del__')
        return func(self, *args, **kwargs)

    return wrappers


_ProactorBasePipeTransport.__del__ = explicit_call(_ProactorBasePipeTransport.__del__)

asyncio.run(main())

Printed firstcall _ProactorBasePipeTransport.__del__ Then report an error, the description is used _proactorbasepiPipetransport

Status: 200
Content-type: text/html
Body: <html>
 ...
call _ProactorBasePipeTransport.__del__
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000001B11653EF70>
Traceback (most recent call last):
  File "D:CodesSpiderProjectBingImageSpiderdemo.py", line 16, in wrappers
    return func(self, *args, **kwargs)
  File "D:DevToolsPythonlibasyncioproactor_events.py", line 116, in __del__
    self.close()
  File "D:DevToolsPythonlibasyncioproactor_events.py", line 108, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "D:DevToolsPythonlibasynciobase_events.py", line 746, in call_soon
    self._check_closed()
  File "D:DevToolsPythonlibasynciobase_events.py", line 510, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

The process has ended, exit the code is 0

solution

If you insist on continuing development under Windows, there have been these programs to choose

1. Do not use Run functions

Since _ProactorBasePiPipTransport will automatically turn off the event loop after the end, don’t use the Run function, use the official website, use loop.

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

2. Alternative event loops

Replace the default proactoreventloop as SelectoreventLoop before calling the Run function

asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
asyncio.run(main())

But SelectoreventLoop has some shortcomings, such as unsupported sub-process, etc.

3. Ignore the abnormality

This is a method of github on a foreign big . Using the decorator to ignore anomalies without changing the source code.

import asyncio
from asyncio.proactor_events import _ProactorBasePipeTransport
from functools import wraps

import aiohttp


async def main():
    async with aiohttp.ClientSession() as session:
        async with session.get('https://www.baidu.com') as response:
            print("Status:", response.status)
            print("Content-type:", response.headers['content-type'])

            html = await response.text()
            print("Body:", html[:15], "...")


def silence_event_loop_closed(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        try:
            return func(self, *args, **kwargs)
        except RuntimeError as e:
            if str(e) != 'Event loop is closed':
                raise

    return wrapper


_ProactorBasePipeTransport.__del__ = silence_event_loop_closed(_ProactorBasePipeTransport.__del__)

asyncio.run(main())

More detailed information can be found on this Issue:https://github.com/aio-libs/aiohttp/issues/4324 👈

Related Links:

  • https://github.com/aio-libs/aiohttp/issues/4324
  • https://stackoverflow.com/questions/45600579/asyncio-event-loop-is-closed-when-getting-loop
  • https://docs.python.org/zh-cn/3/library/asyncio-platforms.html#windows
  • https://bugs.python.org/issue39232

If you like my article, welcomefocus on👇like👇Comment👇collectThank you for your support! ! !

Currently learning about async, and it’s been a real challenge converting sync -> async. For example, the script below parses URLs from a text file, converts them into a list, then, using async, gets the status code of each URL and appends it next to the URL itself.

import requests, aiohttp, asyncio, re

apple = []
link = f"https://pastebin.com/raw/MW2KJNc3"
h = requests.get(link).text
urls = re.findall(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', h)

for url in urls:
    apple.append(f"{url}")

funny = []

async def get_pokemon(session):
        resp = await session.get(url)
        status_code = resp.status
        funny.append((url, status_code))
async def main():
    async with aiohttp.ClientSession() as session:
        tasks = []
        for url  in apple:
            tasks.append(asyncio.create_task(get_pokemon(session)))

        original_pokemon = await asyncio.gather(*tasks)
        for url, status_code in funny:
            apple.append(f"{url} {status_code}")

asyncio.run(main())

Unfortunately though, I keep running into an error. How can I fix this RuntimeError: Event loop is closed error? Thank you!!

Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000002A993A7B9A0>
Traceback (most recent call last):
  File "C:UsersLopsidedAppDataLocalProgramsPythonPython310libasyncioproactor_events.py", line 116, in __del__
    self.close()
  File "C:UsersLopsidedAppDataLocalProgramsPythonPython310libasyncioproactor_events.py", line 108, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "C:UsersLopsidedAppDataLocalProgramsPythonPython310libasynciobase_events.py", line 745, in call_soon
    self._check_closed()
  File "C:UsersLopsidedAppDataLocalProgramsPythonPython310libasynciobase_events.py", line 510, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000002A993A7B9A0>
Traceback (most recent call last):
  File "C:UsersLopsidedAppDataLocalProgramsPythonPython310libasyncioproactor_events.py", line 116, in __del__
    self.close()
  File "C:UsersLopsidedAppDataLocalProgramsPythonPython310libasyncioproactor_events.py", line 108, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "C:UsersLopsidedAppDataLocalProgramsPythonPython310libasynciobase_events.py", line 745, in call_soon
    self._check_closed()
  File "C:UsersLopsidedAppDataLocalProgramsPythonPython310libasynciobase_events.py", line 510, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000002A993A7B9A0>
Traceback (most recent call last):
  File "C:UsersLopsidedAppDataLocalProgramsPythonPython310libasyncioproactor_events.py", line 116, in __del__
    self.close()
  File "C:UsersLopsidedAppDataLocalProgramsPythonPython310libasyncioproactor_events.py", line 108, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "C:UsersLopsidedAppDataLocalProgramsPythonPython310libasynciobase_events.py", line 745, in call_soon
    self._check_closed()
  File "C:UsersLopsidedAppDataLocalProgramsPythonPython310libasynciobase_events.py", line 510, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

Здраствуйте, недавно начал писать асинхронный парсер для cs money (только учусь программированию) и столкнулся с следующей ошибкой :

Код:

self._context.run(self._callback, *self._args)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
<coroutine object ClientResponse.text at 0x000001B5F9DAAF80>
0.8101880550384521
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000001B5F95232E0>
Traceback (most recent call last):
  File "C:UsersKwuuuwhAppDataLocalProgramsPythonPython310libasyncioproactor_events.py", line 116, in __del__
    self.close()
  File "C:UsersKwuuuwhAppDataLocalProgramsPythonPython310libasyncioproactor_events.py", line 108, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "C:UsersKwuuuwhAppDataLocalProgramsPythonPython310libasynciobase_events.py", line 750, in call_soon 
    self._check_closed()
  File "C:UsersKwuuuwhAppDataLocalProgramsPythonPython310libasynciobase_events.py", line 515, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

Собственно сам код:

Python:

from fake_useragent import UserAgent
import random
import asyncio
import aiohttp
import time
import json

data = []

async def get_html_data(url, session):
    headers = {"user-agent": UserAgent().random}

    async with session.get(url=url, headers=headers) as resp:
        response = resp.text()
        print(response)

async def create_task_html():
    async with aiohttp.ClientSession() as session:
        tasks = []

        for offset in range(0, 2):
            url = f'https://inventories.cs.money/5.0/load_bots_inventory/730?limit=32&offset={offset}&order=desc&priceWithBonus=30&sort=price&withStack=true'
            task = asyncio.create_task(get_html_data(url, session))
            tasks.append(task)

        await asyncio.gather(*tasks)

def main():
    start_time = time.time()

    asyncio.run(create_task_html())

    finish_time = time.time() - start_time
    print(finish_time)

if __name__ == '__main__':
    main()

Пытался решить проблему путём добавления в функцию main() за место asyncio.run(create_task_html()) следующую команду:
asyncio.get_event_loop().run_until_complete(create_task_html()) ,но в итоге в вывод идёт сначала:

Код:

<html>
<head><title>429 Too Many Requests</title></head>
<body>
<center><h1>429 Too Many Requests</h1></center>
<hr><center>nginx</center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->

<html>
<head><title>429 Too Many Requests</title></head>
<body>
<center><h1>429 Too Many Requests</h1></center>
<hr><center>nginx</center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->

после желаемый мне вывод и в заключении ошибка из начала

windows 10 pro
python — 3.10.5
aiohttp 3.7.4.post0
asyncio 3.4.3

Context

  • Operating System: Windows 10
  • Python Version: 3.9, 3.10
  • aiogram version: 2.19, 3.0.0b2
  • aiohttp version: 3.8.1

Expected Behavior

Process finishes gracefully

Current Behavior

Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x00000207916D4040>
Traceback (most recent call last):
  File "C:UsersuserAppDataLocalProgramsPythonPython39libasyncioproactor_events.py", line 116, in __del__
    self.close()
  File "C:UsersuserAppDataLocalProgramsPythonPython39libasyncioproactor_events.py", line 108, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "C:UsersuserAppDataLocalProgramsPythonPython39libasynciobase_events.py", line 746, in call_soon
    self._check_closed()
  File "C:UsersuserAppDataLocalProgramsPythonPython39libasynciobase_events.py", line 510, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

Failure Information (for bugs)

Steps to Reproduce

import asyncio

from aiogram import Bot

TOKEN = ""  # put your token here
CHAT_ID = 0  # put your user ID here


async def main():
    bot = Bot(TOKEN)
    await bot.send_message(CHAT_ID, "Hello there!")
    await bot.session.close()  # replace with `await bot.close()` on 2.x
    # await asyncio.sleep(0.1)


if __name__ == '__main__':
    asyncio.run(main())

If you uncomment sleep method, it works fine and finishes without traceback. I guess the problem is in aiohttp.
The message is delivered anyway, with or without sleep

Понравилась статья? Поделить с друзьями:
  • Runtimebroker exe что это за процесс windows 10 как отключить
  • Runtimebroker exe runtime broker windows 10
  • Runtime140 dll скачать для windows 7 x64
  • Runtime библиотеки скачать для windows 10 64 bit
  • Runtime pack для windows 7 64 bit скачать