asyncio.timeout() 不是 asyncio.wait_for() 的替代品:前者仅提供超时检查且不取消协程,后者显式调度任务并抛 CancelledError;3.11+ wait_for() 默认 strict=True,对已完成协程调用 cancel 会报 RuntimeError。

asyncio.timeout() 不再是上下文管理器的替代品
Python 3.11 引入了 asyncio.timeout(),但它**不是** asyncio.wait_for() 的语法糖或轻量替代。它只提供超时上下文管理行为,内部不封装任务调度逻辑;而 wait_for() 会显式创建任务、处理取消、转发异常——两者职责完全不同。
常见错误是写成这样:
async with asyncio.timeout(1):
await some_coro() # ❌ 如果 some_coro() 内部阻塞或未响应 cancel,timeout 不会强制中断它原因在于 timeout() 只在进入/退出时检查时间,并依赖协程主动 await 可取消点(如 asyncio.sleep()、await reader.read())才能响应取消。它不干预协程执行流。
asyncio.wait_for() 在 3.11+ 默认启用 strict=True
从 3.11 开始,asyncio.wait_for() 的 strict 参数默认为 True。这意味着:如果被等待的协程已结束(无论成功或失败),再调用 cancel() 会抛出 RuntimeError: Cannot cancel task when it is in a finished state。
典型触发场景:
- 协程执行极快,在
wait_for()来得及注册取消前就完成了 - 超时时间设得过大,但目标协程本身瞬间返回
- 协程内抛出未捕获异常,导致任务提前终止
解决办法是显式传 strict=False:
await asyncio.wait_for(some_coro(), timeout=5, strict=False)
否则你会在日志里反复看到那个 RuntimeError,尤其在压测或高并发 I/O 场景下。
无论从何种情形出发,在目前校长负责制的制度安排下,中小学校长作为学校的领导者、管理者和教育者,其管理水平对于学校发展的重要性都是不言而喻的。从这个角度看,建立科学的校长绩效评价体系以及拥有相对应的评估手段和工具,有利于教育行政机关针对校长的管理实践全过程及其结果进行测定与衡量,做出价值判断和评估,从而有利于强化学校教学管理,提升教学质量,并衍生带来校长转变管理观念,提升自身综合管理素质。
timeout() 和 wait_for() 对 CancelledError 的处理差异
当超时发生时:
-
wait_for()总是向被包装协程抛出CancelledError,并等待其完成清理(除非它忽略取消) -
timeout()仅在__aexit__阶段检查是否超时,若超时则抛出TimeoutError,**不会主动 cancel 任何协程** —— 它甚至不知道你在await什么
也就是说,如果你写:
async with asyncio.timeout(0.1):
await asyncio.sleep(1) # ✅ 会被 sleep 中断,因为 sleep 是可取消的
async with asyncio.timeout(0.1):
await slow_cpu_bound_func() # ❌ 不会中断,只是最后抛 TimeoutError,slow_cpu_bound_func 继续跑这种差异决定了:想真正中断长时间运行的协程,必须用 wait_for();只想给一段代码块加“截止时间提示”,用 timeout() 更轻量。
实际选型建议:看你要中断还是仅标记
选 wait_for() 当:
- 需要确保协程在超时后停止执行(比如防止连接泄漏、避免资源占用)
- 要统一捕获
TimeoutError或CancelledError - 目标协程明确支持取消(即内部有
await点)
选 timeout() 当:
- 只是给一段逻辑加“最晚截止时间”,不关心它是否真停了
- 嵌套多个异步操作,且不想层层透传
timeout参数 - 配合
asyncio.create_task()自行管理生命周期(此时你控制 cancel 时机)
最容易被忽略的一点:3.11+ 的 wait_for() 在 strict=True 下对“已完成协程”的容忍度极低,而很多旧代码假设它总是静默忽略重复 cancel —— 这个行为变化会在升级后突然暴露出来。









