python
runtime_error
ai_generated
true
RuntimeError: 事件循环已关闭
RuntimeError: Event loop is closed
ID: python/event-loop-closed
80%修复率
88%置信度
0证据数
2024-03-12首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 3.8 | active | — | — | — |
| 3.9 | active | — | — | — |
| 3.10 | active | — | — | — |
| 3.11 | active | — | — | — |
| 3.12 | active | — | — | — |
根因分析
在事件循环已关闭后仍尝试执行异步操作,通常是因为在多次调用 asyncio.run() 时复用了同一个 loop 对象,或手动调用了 loop.close()。
English
An async operation was attempted after the event loop had already been closed, typically when reusing a loop object across multiple asyncio.run() calls or after calling loop.close() manually.
解决方案
-
95% 成功率
Use asyncio.run(main()) as the single entry point and never call loop.close() manually. asyncio.run creates and closes the loop for you. async def main(): ... if __name__ == '__main__': asyncio.run(main()) -
85% 成功率
If you must reuse a loop (e.g. in tests), use asyncio.new_event_loop() per test and call loop.close() only in teardown: loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: loop.run_until_complete(coro()) finally: loop.close() -
90% 成功率
For aiohttp/aiofiles contexts, ensure the ClientSession is created and closed inside the same asyncio.run scope: async def main(): async with aiohttp.ClientSession() as s: await s.get(url) asyncio.run(main())
无效尝试
常见但无效的做法:
-
65% 失败
Creates a new loop but the pending coroutine/task still references the old closed loop's internals, causing the same error deeper in the stack.
-
80% 失败
Swallows the error but the awaited work never completes, leading to silent data loss downstream.
-
90% 失败
Raises the same RuntimeError immediately because the loop state is terminal.