switch适合3状态以内、同步变更、无副作用的异步流程控制;状态需用单一字段定义,变更与ui/日志等副作用分离,异步任务应在状态变更后启动并回调更新状态。

用 switch 编排异步任务的状态生命周期,关键不是“能不能用”,而是“在什么边界内用得稳”。它适合轻量、线性、无副作用的异步流程控制,比如表单提交、按钮点击反馈、简单 API 调用链——状态少、跳转明确、不涉及定时器/上下文传递/多入口拦截。
明确适用范围:3 状态以内 + 同步变更 + 无钩子需求
switch 方案真正能“平滑”运行的前提是:状态总数 ≤3(如 idle → pending → success/error),且所有状态变更都是同步完成的。一旦出现以下任一情况,就该切换到 StatePattern 或专用状态机库:
- 某个状态需要启动并持有 Timer 或 CancellationTokenSource
- 进入 pending 状态后要同时更新 UI、记录日志、触发埋点——这些属于副作用,但不能阻塞状态赋值本身
- 外部可能从任意状态直接跳转到 error(比如网络中断信号),而你希望统一拦截非法跳转
- 需要对每个状态单独做单元测试,或复用同一套状态逻辑到多个组件中
状态变量必须是单一可读字段,且只在 switch 内部赋值
不要把状态藏在嵌套对象里,也不要靠多个布尔标志位拼凑状态。定义一个清晰的 enum 或 string 类型字段(如 RequestState),所有状态流转都通过一次赋值完成:
enum RequestState { Idle, Pending, Success, Error }
// ✅ 正确:状态变更与副作用分离
private RequestState _state = RequestState.Idle;
private void Transition(RequestState newState) {
switch (_state) {
case RequestState.Idle when newState == RequestState.Pending:
_state = newState;
ShowLoading();
break;
case RequestState.Pending when newState is RequestState.Success or RequestState.Error:
_state = newState;
HideLoading();
break;
default:
throw new InvalidOperationException($"Invalid transition: {_state} → {newState}");
}
}
注意:show/hide 操作是副作用,不是状态本身;状态字段 _state 的赋值必须原子、不可中断。
动态切换AI模型以优化成本与性能。当用户发出“eco mode”、“balanced mode”、“smart mode”或“max mode”等模式指令,或使用“/modes status”查询状态及“/modes setup”配置模式时触发。
异步动作只能作为状态变更的“后续响应”,不能参与状态判断
常见错误是在 case Pending: 里直接 await 一个 Task,以为“等它完了才算真正进入 Pending”。这会导致状态已变、UI 已更新,但后台还在跑,外部逻辑却误判流程已完成。
- 正确做法:在
Transition(Pending)后立即启动异步任务(如Task.Run(...)或SendAsync()),但不 await 它 - 任务完成后,再调用
Transition(Success)或Transition(Error)—— 这次才是真正的状态闭环 - 若需超时控制,用独立的
CancellationTokenSource监听,超时后主动触发Transition(Error)
配合 UI 更新时,确保状态驱动而非轮询
不要在 Update 或 render 函数里写 if (_state == Pending) { showSpinner(); }。应把状态映射为只读属性或响应式信号:
public bool IsLoading => _state == RequestState.Pending; public bool HasSucceeded => _state == RequestState.Success;
前端框架(如 Blazor、MAUI 或 Avalonia)可绑定这些属性,实现自动刷新。这样既避免重复判断,又让 UI 成为状态的自然投影,而不是状态的“猜测者”。










