# YZWater3 性能优化计划 > 创建时间:2026-09-01 01:12 > 计划执行时间:2026-09-01 03:14(定时触发逐个完成) --- ## 已知编译问题(已修复) | 文件 | 行号 | 问题 | 状态 | |------|------|------|------| | `DeviceStateMachine.cs` | 122 | `OnTransitionException` 在 Stateless 5.20.1 中不存在 | ✅ 已修复:改用 FireSafe() 包裹异常 | --- ## 优化任务清单 ### 🔴 高优先级(直接影响用户体验) #### 任务1: UI定时器无效重绘 - PumpStation2DControl - **文件**: `src/YZWater.Avalonia/Controls/PumpStation2DControl.cs:98` - **问题**: 33ms定时器(30FPS)每帧无条件调用 `InvalidateVisual()`,即使没有泵/风扇在运行 - **修复**: 仅在动画状态变化(泵转动、风扇转动)时才调用 `InvalidateVisual()` - **预期收益**: 静止画面CPU占用降低80%+ #### 任务2: UI定时器无效重绘 - PumpStation3DControl - **文件**: `src/YZWater.Avalonia/Controls/PumpStation3DControl.cs:89` - **问题**: 40ms定时器(25FPS)每帧无条件 `InvalidateVisual()` - **修复**: 同上,仅在状态变化时重绘 - **预期收益**: 同任务1 #### 任务3: 渲染循环中 SolidColorBrush 缓存 - **文件**: `PumpStation2DControl.cs:274,279,297`、`PumpStation3DControl.cs:154,156,167` - **问题**: 每帧 `new SolidColorBrush()` 产生大量GC压力 - **修复**: 将常用颜色缓存为 `static readonly` 字段 - **预期收益**: 减少GC频率,消除画面卡顿 #### 任务4: 渲染循环中 FormattedText 缓存 - **文件**: `GaugeControl.cs:63-70`、`PumpStation2DControl.cs` 多处 `DrawLabel` - **问题**: 每帧创建 `FormattedText` 对象,文本测量开销大 - **修复**: 文本不变时复用 FormattedText 实例 - **预期收益**: 减少CPU开销 ### 🟡 中优先级(内存泄漏 + 数据层) #### 任务5: 事件处理器泄漏 - MainViewModel - **文件**: `src/YZWater.Core/ViewModels/MainViewModel.cs:411-412` - **问题**: `Dispose()` 只释放 ViewA 和 Project ViewModel,ViewB~ViewF 未释放 - **修复**: 补全所有子 ViewModel 的 Dispose 调用 - **预期收益**: 防止内存持续增长 #### 任务6: 事件处理器泄漏 - ViewAViewModel - **文件**: `src/YZWater.Core/ViewModels/ViewAViewModel.cs:171-175` - **问题**: 订阅静态单例事件但 Dispose 可能不被调用 - **修复**: 在 View 的 Unloaded 事件中确保 Dispose 被调用 - **预期收益**: 防止重复导航导致的内存泄漏 #### 任务7: 数据库N+1查询 - **文件**: `src/YZWater.Core/Services/DataLoggingService.cs:66-77` - **问题**: 全表加载 `EquipmentStatus` 再 GroupBy 取最新 - **修复**: 使用 SQL 子查询,只取每个设备最新记录 - **预期收益**: 启动速度提升,内存占用降低 #### 任务8: 数据库索引缺失 - **文件**: `src/YZWater.Core/Services/DatabaseService.cs:46-61` - **问题**: 表创建时未定义索引 - **修复**: 给 `RecordTime`、`AlarmTime`、`LastUpdateTime`、`DeviceId` 添加索引 - **预期收益**: 查询性能提升 #### 任务9: PLC读取未批量化(ProjectProfile模式) - **文件**: `src/YZWater.Core/Services/PlcPollingService.cs:361-368` - **问题**: 逐点读取,20个模拟量=20次网络请求 - **修复**: 按地址分组,使用批量读取 - **预期收益**: 网络开销大幅降低 ### 🟢 低优先级(代码质量) #### 任务10: ViewModel过度属性通知 - **文件**: `src/YZWater.Core/ViewModels/ViewAViewModel.cs:268-320` - **问题**: 每次PLC更新(1Hz)触发30+个PropertyChanged,不管值是否变化 - **修复**: 赋值前比较新旧值,仅在值变化时通知 #### 任务11: WebSocket MemoryStream分配 - **文件**: `HubServer.cs:232-250`、`HubClient.cs:283-296` - **问题**: 每条消息 `new MemoryStream()` - **修复**: 使用 `ArrayPool` 复用缓冲区 #### 任务12: 日志优化 - **文件**: `src/YZWater.Core/Services/LogService.cs:20,22` - **问题**: Debug级别过高 + 同步文件写入 - **修复**: 生产环境改为 Information,添加 `buffered: true` --- ## 执行顺序 按优先级从高到低逐个执行: 1. 任务1~4(UI渲染优化) 2. 任务5~6(内存泄漏修复) 3. 任务7~9(数据层优化) 4. 任务10~12(代码质量优化) 每个任务完成后立即 `dotnet build` 验证编译通过。 --- ## 完成后归档 所有问题点和修复记录归档至本目录 (`docs/`)。