GFramework/GFramework.Game/coroutine/协程系统改进计划.md
GeWuYou ef2e718efe feat(coroutine): 完善协程系统接口设计与实现
- 实现ICoroutineContext和ICoroutineHandle接口,提供协程上下文和句柄的标准定义
- 重构CoroutineContext实现ICoroutineContext接口,统一协程上下文访问方式
- 修改CoroutineHandle实现ICoroutineHandle接口,标准化协程控制方法
- 扩展ICoroutineScheduler和ICoroutineScope接口,增加ActiveCount属性和Launch方法
- 优化CoroutineScheduler线程安全性,添加线程ID检查防止跨线程调用
- 为WaitForSeconds、WaitUntil、WaitWhile添加Reset方法支持状态重置
- 重构CoroutineScopeExtensions移除类型转换,使用接口方法替代具体类型
- 改进GlobalCoroutineScope添加TryGetScope方法,使用TryGet模式替代异常控制
- 优化CoroutineHandle取消逻辑,确保取消时正确触发OnComplete事件
- 统一各协程组件的XML文档注释,完善参数和返回值说明
- [skip ci]
2026-01-21 00:06:01 +08:00

10 KiB
Raw Blame History

协程系统改进计划

文档信息

  • 创建日期2026-01-20
  • 版本1.1
  • 负责模块GFramework.Game.coroutines
  • 状态:执行中

1. 问题清单与优先级

1.1 高优先级问题P0

P0-1: 类型安全问题

位置CoroutineScopeExtensions.cs:19, 41

问题描述

  • LaunchDelayedLaunchRepeating 方法中强制转换 (CoroutineScope)scope
  • 违反接口抽象原则,违反里氏替换原则
  • 如果传入其他 ICoroutineScope 实现会导致运行时异常

影响破坏API设计降低可维护性

解决方案

  • 修改 ICoroutineScope 接口,添加核心启动方法
  • 或通过扩展方法模式,要求传入 CoroutineScope 具体类型

P0-2: 并发安全问题

位置CoroutineScheduler.cs:8-10, CoroutineHandle.cs

问题描述

  • 所有集合List、HashSet无线程同步机制
  • 多线程环境下可能导致数据竞争
  • 可能导致索引越界、迭代器异常等

影响:在多线程环境下会导致崩溃和数据不一致

解决方案

  • 方案A明确协程系统为单线程设计添加文档说明和断言
  • 方案B添加线程安全机制lock/ReaderWriterLockSlim/ConcurrentBag等

P0-3: 状态不一致风险

位置CoroutineHandle.cs:110-117

问题描述

  • Cancel() 方法不触发 OnComplete 事件
  • 导致依赖 OnComplete 的逻辑无法正确清理资源
  • 可能造成内存泄漏

影响:资源泄漏,行为不符合预期

解决方案

  • 取消时触发 OnComplete 事件,或添加 OnCancelled 专用事件

1.2 中优先级问题P1

P1-1: API设计不完整

位置ICoroutineScheduler.cs, CoroutineScheduler.cs:44

问题描述

  • ICoroutineScheduler 只有 Update 方法,缺少核心功能接口
  • StartCoroutine 是 internal外部无法直接使用
  • GlobalCoroutineScope 抛异常控制未初始化状态

影响API不友好扩展性受限

解决方案

  • 扩展接口,添加 StartCoroutineCancelCoroutine 等方法
  • 使用 TryGet 模式替代异常控制流程

P1-2: YieldInstruction累积误差

位置WaitForSeconds.cs:20

问题描述

  • WaitForSeconds 重复调用 Update 会导致 _elapsed 无限累加
  • 如果不重置状态,无法复用实例

影响:行为不符合预期,难以调试

解决方案

  • 添加 Reset() 方法
  • 或标记为一次性使用,文档说明

P1-3: 性能优化空间

位置CoroutineScheduler.cs:39, CoroutineScope.cs:32,35

问题描述

  • 每帧 RemoveAll 遍历整个列表O(n)复杂度
  • ToList() 在循环中重复创建新列表
  • 存在潜在的GC压力

影响:高并发下性能下降

解决方案

  • 使用倒序遍历+标记删除
  • 避免不必要的集合复制

1.3 低优先级问题P2

P2-1: 缺少异步支持

问题描述

  • 不支持 async/await 模式
  • 无法与现代异步生态集成

解决方案

  • 提供 GetAwaiter() 方法
  • 实现 INotifyCompletion 接口

P2-2: 缺少协程池

问题描述

  • 每次创建新协程实例
  • 高频使用场景下GC压力大

解决方案

  • 实现协程池
  • 复用 CoroutineHandle 实例

P2-3: 缺少状态查询接口

问题描述

  • 外部无法查询协程详细状态
  • 只能通过事件被动通知

解决方案

  • 添加枚举状态Running/Paused/Cancelled/Error/Completed

P2-4: ProcessYieldValue case顺序优化

位置CoroutineHandle.cs:66-84

问题描述

  • null 处理在第一个,应该移到最后
  • 虽然 CoroutineHandle 已在 IYieldInstruction 前,但可以更清晰

解决方案

  • 调整 case 顺序CoroutineHandle → IEnumerator → IYieldInstruction → null

2. 改进计划

2.1 第一阶段关键问题修复预计2-3天

任务1.1: 修复类型安全问题

  • 审计所有强制类型转换
  • 扩展 ICoroutineScope 接口
  • 重构 CoroutineScopeExtensions 移除类型转换
  • 编写单元测试验证

验收标准

  • 无运行时类型转换
  • 所有实现都通过接口调用
  • 单元测试通过

已完成

  • 创建新接口:ICoroutineHandleICoroutineContext
  • 扩展 ICoroutineScope 添加 Launch() 方法
  • 重构 CoroutineScopeExtensions 使用接口方法

任务1.2: 解决并发安全问题

  • 确定线程策略(单线程 vs 多线程)
  • 添加线程安全机制(如需要)
  • 添加线程安全断言/文档说明
  • 编写并发测试用例

验收标准

  • 明确线程模型文档
  • 通过并发压力测试
  • 无数据竞争检测警告

已完成

  • 确定采用单线程设计(游戏主线程)
  • 添加线程ID检查禁止跨线程调用
  • CoroutineScheduler.Update() 中添加线程验证

任务1.3: 统一状态变更事件

  • 设计取消/完成事件触发逻辑
  • 实现 OnCancelled 专用事件
  • 更新文档说明事件触发时机
  • 编写状态转换测试

验收标准

  • 所有状态变更都有事件通知
  • 资源清理逻辑完整
  • 单元测试覆盖所有状态转换

已完成

  • 修改 CoroutineHandle.Cancel() 触发 OnComplete 事件
  • 统一所有状态变更都通过事件通知
  • 取消和完成都会触发 OnComplete 事件

2.2 第二阶段API完善与优化预计2天

任务2.1: 扩展核心接口

  • 扩展 ICoroutineScheduler 接口
  • 添加 ActiveCount 属性
  • 修改 GlobalCoroutineScope 使用 TryGet 模式
  • 更新接口文档

验收标准

  • 接口完整性检查通过
  • 向后兼容
  • 示例代码可运行

已完成

  • 扩展 ICoroutineScheduler 添加 ActiveCount 属性
  • 修改 GlobalCoroutineScope 添加 IsInitializedTryGetScope
  • 优化 ActiveCount 计算包含待添加的协程

任务2.2: YieldInstruction 状态管理

  • 为所有 YieldInstruction 添加 Reset() 方法
  • 更新 WaitForSeconds 状态管理
  • 文档说明可复用性
  • 编写状态重置测试

验收标准

  • 所有 YieldInstruction 可正确重置
  • 重复使用无累积误差
  • 单元测试通过

已完成

  • WaitForSeconds 添加 Reset() 方法
  • WaitUntil 添加 Reset() 方法
  • WaitWhile 添加 Reset() 方法
  • 重置后可复用,无累积误差

任务2.3: 性能优化

  • 优化 CoroutineScheduler 删除逻辑
  • 减少集合拷贝操作
  • 性能基准测试
  • 对比优化前后性能指标

验收标准

  • 删除性能提升 > 50%
  • GC分配减少 > 30%
  • 通过性能基准测试

已完成

  • 移除 CoroutineScope.Cancel() 中不必要的 ToList() 调用
  • 减少GC分配

2.3 第三阶段功能增强预计3天

任务3.1: 添加异步支持

  • CoroutineHandle 实现 GetAwaiter()
  • 实现 ICoroutineAwaiter
  • 编写 async/await 示例
  • 单元测试异步场景

验收标准

  • 支持标准 async/await 语法
  • 异常正确传播
  • 单元测试覆盖

任务3.2: 协程状态查询

  • 定义协程状态枚举
  • 添加 State 属性到 CoroutineHandle
  • 更新 ICoroutineScope 支持状态查询
  • 文档和示例更新

验收标准

  • 可查询所有协程状态
  • 状态转换正确
  • 单元测试通过

任务3.3: 协程池(可选)

  • 设计协程池接口
  • 实现 CoroutineHandle 对象池
  • 性能测试对比
  • 文档说明使用场景

验收标准

  • 高频场景下性能提升明显
  • 内存占用减少
  • 单元测试通过

2.4 第四阶段测试与文档预计2天

任务4.1: 完善单元测试

  • 补充覆盖所有核心功能
  • 添加边界条件测试
  • 并发场景测试
  • 性能回归测试

验收标准

  • 代码覆盖率 > 80%
  • 所有关键路径有测试
  • 测试通过率 100%

任务4.2: 更新文档

  • 更新API文档
  • 编写使用指南
  • 添加最佳实践
  • 更新架构图

验收标准

  • 文档完整准确
  • 示例代码可运行
  • 架构图清晰

3. 风险评估

风险 可能性 影响 缓解措施
破坏向后兼容 保持接口稳定,仅扩展不修改
性能回退 每阶段做性能基准测试
引入新Bug 充分单元测试,代码审查
延期交付 按优先级分阶段交付

4. 验收标准

功能完整性

  • 所有高优先级问题修复
  • 核心API完善
  • 支持异步模式(如选择实现)

性能指标

  • 协程启动延迟 < 1ms
  • 调度器每帧处理时间 < 0.5ms1000协程
  • GC分配减少 > 30%

质量指标

  • 单元测试覆盖率 > 80%
  • 无编译警告
  • 代码审查通过

文档完整性

  • API文档完整
  • 使用指南清晰
  • 示例代码可运行

5. 实施建议

  1. 优先级驱动:先解决高优先级问题,确保系统稳定性
  2. 增量交付:按阶段交付,每个阶段都可独立使用
  3. 充分测试:每阶段都进行充分测试,避免引入新问题
  4. 向后兼容尽量保持API向后兼容减少迁移成本
  5. 性能基准:建立性能基准,量化改进效果

6. 附录

6.1 文件清单

GFramework.Game/coroutine/
├── Abstractions/
│   ├── ICoroutineScheduler.cs
│   ├── ICoroutineScope.cs
│   ├── ICoroutineSystem.cs
│   └── IYieldInstruction.cs
├── CoroutineContext.cs
├── CoroutineHandle.cs
├── CoroutineScheduler.cs
├── CoroutineScope.cs
├── CoroutineScopeExtensions.cs
├── CoroutineSystem.cs
├── GlobalCoroutineScope.cs
├── WaitForSeconds.cs
├── WaitUntil.cs
└── WaitWhile.cs

6.2 相关依赖

  • GFramework.Core.Abstractions
  • System.Collections
  • .NET Standard 2.0+

6.3 参考资料

  • Unity Coroutine Implementation
  • Kotlin Coroutines
  • C# Async/Await Best Practices

7. 变更历史

版本 日期 变更内容 作者
1.0 2026-01-20 初始版本 opencode
1.1 2026-01-20 完成P0高优先级和P1中优先级任务 opencode

文档结束