如何修复 asyncio RuntimeError: This event loop is already running

问题

尝试使用 asyncio.run_until_complete() 运行 async def 函数时,例如

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 等上下文运行代码,会出现此错误,因为 Jupyter 在内部启动了事件循环。如果你想在纯 Python 脚本等其他上下文中运行它,可能需要修改代码。


Check out similar posts by category: Python