Як виправити asyncio RuntimeError: This event loop is already running

Проблема

Під час спроби запустити функцію async def за допомогою asyncio.run_until_complete(), наприклад

asyncio_example.py
import asyncio
asyncio.get_event_loop().run_until_complete(asyncio.sleep(1))

ви бачите повідомлення про помилку на кшталт

asyncio_runtimeerror_example.txt
Cell In[3], line 15
     12           raise
     14 # Usage example:
---> 15 asyncio.get_event_loop().run_until_complete(asyncio.sleep(1))

File /usr/lib/python3.12/asyncio/base_events.py:663, in BaseEventLoop.run_until_complete(self, future)
    652 """Run until the Future is done.
    653
    654 If the argument is a coroutine, it is wrapped in a Task.
   (...)
    660 Return the Future's result, or raise its exception.
    661 """
    662 self._check_closed()
--> 663 self._check_running()
    665 new_task = not futures.isfuture(future)
    666 future = tasks.ensure_future(future, loop=self)

File /usr/lib/python3.12/asyncio/base_events.py:622, in BaseEventLoop._check_running(self)
    620 def _check_running(self):
    621     if self.is_running():
--> 622         raise RuntimeError('This event loop is already running')
    623     if events._get_running_loop() is not None:
    624         raise RuntimeError(
    625             'Cannot run the event loop while another loop is running')

RuntimeError: This event loop is already running

Рішення

Замість використання loop.run_until_complete(), використовуйте asyncio.create_task() для запуску корутини:

asyncio_create_task.py
future = asyncio.get_event_loop().create_task(asyncio.sleep(1))

За бажанням ви можете await future, щоб дочекатися завершення корутини:

asyncio_await_future.py
await future

Причина в тому, що loop.run_until_complete() призначений для синхронного коду і завжди запускає цикл, тому він завершиться помилкою, якщо цикл уже працює.

Зазвичай ця помилка виникає, якщо ви запускаєте код із контексту на кшталт Jupyter Notebook, який запускає цикл подій внутрішньо. Можливо, вам доведеться змінити свій код, якщо ви хочете запустити його в іншому контексті, наприклад у чистому Python-скрипті.


Дивіться схожі статті за категоріями: Python