mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-25 21:34:28 +08:00
- 重命名命名空间从GFramework.Game.Abstractions.coroutine到GFramework.Core.Abstractions.coroutine - 更新ICoroutineContext.cs、ICoroutineHandle.cs、ICoroutineScheduler.cs、 ICoroutineScope.cs、ICoroutineSystem.cs、IYieldInstruction.cs的命名空间 - 更新测试覆盖率计划文档,添加协程模块测试计划 - 新增协程模块测试计划,包含15个源文件,计划91个测试用例 - 添加CoroutineHandleTests.cs等7个协程相关测试文件的计划
10 KiB
10 KiB
协程系统改进计划
文档信息
- 创建日期:2026-01-20
- 版本:1.1
- 负责模块:GFramework.Game.coroutines
- 状态:执行中
1. 问题清单与优先级
1.1 高优先级问题(P0)
P0-1: 类型安全问题
位置:CoroutineScopeExtensions.cs:19, 41
问题描述:
LaunchDelayed和LaunchRepeating方法中强制转换(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不友好,扩展性受限
解决方案:
- 扩展接口,添加
StartCoroutine、CancelCoroutine等方法 - 使用 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移除类型转换 - 编写单元测试验证
验收标准:
- 无运行时类型转换
- 所有实现都通过接口调用
- 单元测试通过
已完成:
- 创建新接口:
ICoroutineHandle、ICoroutineContext - 扩展
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添加IsInitialized和TryGetScope - 优化
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.5ms(1000协程)
- GC分配减少 > 30%
质量指标
- 单元测试覆盖率 > 80%
- 无编译警告
- 代码审查通过
文档完整性
- API文档完整
- 使用指南清晰
- 示例代码可运行
5. 实施建议
- 优先级驱动:先解决高优先级问题,确保系统稳定性
- 增量交付:按阶段交付,每个阶段都可独立使用
- 充分测试:每阶段都进行充分测试,避免引入新问题
- 向后兼容:尽量保持API向后兼容,减少迁移成本
- 性能基准:建立性能基准,量化改进效果
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 |
文档结束