问题现象
在 Jupyter 里跑一段异步代码,直接调用 asyncio.run 立刻报运行时错误,提示已有事件循环在运行。
原因分析
Jupyter 和部分框架常驻一个事件循环,run 会尝试新建并接管循环,与现存循环冲突。判断时先分清是 asyncio 事件循环冲突 本身的配置问题,还是上游调用、运行环境带进来的差异;前者改配置就能收口,后者要沿着请求链路一层层往上找,处理顺序不能颠倒。先在出问题的机器上复现一次,把报错原文和发生时间记下来,再对着日志定位。
处理步骤
- 判断当前是否已有运行中的循环
- 有循环时改用 await 直接调用协程
- 脚本入口处才使用 run
对应的命令或配置片段如下,可直接复制:
import asyncio
async def main():
await asyncio.sleep(1)
try:
loop = asyncio.get_running_loop()
await main()
except RuntimeError:
asyncio.run(main())
改动前把原配置备份一份,出问题时能马上回退,比现场找原因省时间。排查时把每一步的输出留下来,后面再遇到同类问题,对照日志就能判断是哪一层先出错的。
验证结果
同样的调用不再抛异常,任务能按顺序执行完成并打印结果。