背景

Tokio 里 select! 和超时很常用,但取消发生在任意 await 点,任务可能停在中间状态。

实践建议

  1. 把副作用操作放在不可分割阶段
  2. 写操作尽量幂等
  3. 关键路径加补偿或重试机制
tokio::select! {
    _ = shutdown.recv() => {
        tracing::info!("cancelled");
    }
    res = do_commit_work() => {
        res?;
    }
}

总结

取消安全本质是状态机设计,不是语法问题。


异步代码能停下来不难,停得干净才难。