P385 · 测试与评估

检查异步操作的不同完成顺序

Review both overlapping completion orders

组合测试共享状态上的竞争操作,避免只分别检查每个操作。

编辑审核

以下示例与示意结果由本站编写,用于说明方法,不是模型实测结果。

使用场景

编辑器延迟刷新取回旧文档v1,保存已写新文档v2;两项操作都更新同一状态。分别检查它们各自赋值正确,不能排除旧刷新覆盖新保存。

具体做法

声明调用边界与不变量“旧刷新不得覆盖较新保存”。画刷新/保存/共享状态合并时序,在相关await前后设受控暂停。先保存完成再释放刷新,由新消费者读取;再测刷新完成后保存。核版本检查或取消实际阻止哪个时序,不以原子赋值或单线程作顺序证明。保留每条观察与预期。

反例

两函数赋值是原子的,分别测试通过便宣称无竞态,不组合交错。

改进写法

暂停v1刷新应用,先完成v2保存再放行刷新,最终新读取必须v2;再测相反顺序。记录版本/取消门禁及受控关卡结果,若任一顺序不可能,引用具体阻止机制。

为什么这样改

跨await允许竞争动作穿插,单次赋值原子不保护跨操作的新鲜度。组合时序和新读取暴露旧结果覆盖,而不是仅看操作返回。

如何验证

教学无门禁:保存v2后刷新v1,最终v1违反不变量;版本拒绝旧结果后应v2。相反顺序也最终v2。未运行只是预期轨迹;测试应确认等待关卡而非猜测延时。

适用边界

两顺序覆盖相关交错,不是所有并发安全证明。外部持久化、取消有效性与多文档身份还需契约;有例外应明确授权条款,不能以损害有限代替满足要求。

原文与版本

如何收录这些方法