async任务取消本质是抛出cancellederror异常,需协程在await点响应;关键步骤为create_task、cancel()标记、等待结束;应使用try/finally或async with确保资源清理。

async任务取消的本质是抛出CancelledError异常
Python的asyncio中,任务取消不是“硬终止”,而是通过在协程挂起点主动抛出CancelledError异常来实现的。一旦协程捕获该异常并退出(或未捕获而向上冒泡),任务状态即变为cancelled。这意味着:取消操作必须等待协程执行到下一个await点才能生效,无法中断正在运行的同步代码段。
正确取消任务的三个关键步骤
-
创建可取消的任务对象:使用
asyncio.create_task()而非直接await,确保任务在事件循环中独立运行 -
调用
task.cancel():这会向任务调度器标记该任务为“待取消”,但不会立即生效 -
等待任务真正结束:通常配合
asyncio.wait_for(task, timeout=None)或await task(需处理CancelledError)来确认取消完成
如何安全地响应取消(避免资源泄漏)
协程中若有打开的文件、网络连接或锁等资源,应在取消时清理。推荐用try/finally或async with确保释放:
例如:
async def fetch_data():
conn = await open_connection()
try:
return await conn.read()
finally:
await conn.close() # 取消时也会执行
若需在取消发生时做特定处理,可捕获asyncio.CancelledError,但注意不要静默吞掉它——除非你明确要抑制取消(极少见)。
立即学习“Python免费学习笔记(深入)”;
常见陷阱与规避方式
-
在CPU密集型同步代码中无法响应取消:应将耗时计算拆分为多个
await asyncio.sleep(0)让出控制权 -
忽略返回值直接
await task可能引发未处理异常:建议用asyncio.shield()保护关键任务,或显式except CancelledError -
父任务取消后子任务未自动取消:需手动跟踪子任务并在父任务取消时调用其
cancel()










