asyncio.run() 在 python 3.12 中已被弃用,应改用 asyncio.runner;后者支持可重入调用、自动资源清理、与 jupyter 兼容,并避免事件循环泄漏。

因为 asyncio.run() 在 Python 3.12 中虽未报错,但已显式发出 DeprecationWarning,且其隐式单次循环模型在 Jupyter、Web 服务、多任务调度等场景下极易引发 RuntimeError 或资源泄漏。
asyncio.run() 在 Python 3.12 中触发 DeprecationWarning
从 Python 3.12 开始,asyncio.run() 调用时会输出明确警告:
DeprecationWarning: asyncio.run() is deprecated since Python 3.12, use asyncio.Runner instead
这不是“未来计划”,而是已生效的弃用标记。它不阻止运行,但意味着:
- 该函数将在 Python 3.14 或 3.15 中被彻底移除(PEP 705 已确认)
- 所有 CI/CD 流水线、静态检查工具(如 pyright、mypy)和 linter(如 ruff)默认将其视为潜在问题
- 警告无法通过
warnings.filterwarnings()安全忽略——它由 C 层直接抛出,绕过 Python 级过滤
Jupyter / IPython 中必须用 asyncio.Runner
IPython 内核自带一个长期运行的事件循环,asyncio.run() 尝试创建新循环时会直接失败:
RuntimeError: asyncio.run() cannot be called from a running event loop
而 asyncio.Runner 不依赖全局状态,它内部调用 asyncio.new_event_loop() 并严格隔离生命周期:
- 每次
with asyncio.Runner() as runner:都新建私有循环,与内核循环互不干扰 - 支持在同一个 notebook 多次执行,不会因前一次未清理导致后续崩溃
- 无需手动调用
loop.close()——__exit__自动完成清理
需要多次运行协程时,Runner 是唯一安全选择
比如测试多个异步用例、CLI 工具中按子命令分发协程、或 Web 框架中动态加载插件任务:
-
asyncio.run()第二次调用必然抛RuntimeError: asyncio.run() cannot be called when another asyncio.run() is already running -
asyncio.Runner().run()可重复调用:同一实例可连续执行多个协程,每次返回独立结果 - 支持传入
loop_factory,例如注入uvloop.EventLoopPolicy提升性能
示例:
import asyncio<br>import uvloop<br><br>async def task_a(): return "A"<br>async def task_b(): return "B"<br><br># ✅ 安全、可重入<br>runner = asyncio.Runner(loop_factory=uvloop.new_event_loop)<br>result_a = runner.run(task_a())<br>result_b = runner.run(task_b())<br>runner.close() # 显式关闭(with 块自动处理)
生产服务中避免 Event Loop 泄漏的关键
长期运行的服务(如 FastAPI 后台任务、异步定时器、连接池管理)若误用 asyncio.run(),会导致:
- 每次调用都新建循环但未释放底层 selector(尤其在 Linux epoll 或 Windows IOCP 上)
- 残留未 cancel 的
asyncio.TimerHandle和 pending callbacks,内存持续增长 - 日志中出现
ResourceWarning: unclosed event loop却难以定位源头
asyncio.Runner 把循环生命周期收束到一个对象内,with 语句确保 close() 必然执行,哪怕协程中途 raise 异常 —— 这是 asyncio.run() 完全缺失的保障。
真正容易被忽略的是:Runner 不只是“替代 run() 的写法”,它是把事件循环当作可销毁资源来对待的思维切换。一旦你开始手动管理 loop.create_task() 或 loop.call_soon(),就再也不能假装循环是免费的、无限的、自动回收的了。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











