项目学习代码

当然有!你提供的这段 C# WinForms 代码功能非常完整且考虑周全,尤其是在 UI 交互、多线程处理和状态管理方面做得相当不错。

在此基础上,我们可以从性能、架构和代码可维护性三个角度进行优化,让这个应用变得更加出色。

核心性能优化(高优先级)

这两点改进能最显著地提升应用的流畅度和响应速度。

  1. 数据采集:从"轮询"改为"事件驱动"

    问题:

    你现在的后台任务 RefreshDataLoopAsync 是一个轮询循环,它以固定的 50ms 间隔主动去 GetDeviceData。这种方式的主要缺点是:

    ● 不精确:如果设备回报率高于 20Hz (50ms),你会丢失数据点。如果低于 20Hz,则会进行不必要的空查询,浪费 CPU 资源。

    ● 非实时:数据从产生到被你读取,最多有 50ms 的延迟。

    改进方案:

    利用 SDK 提供的 BWT901BLE_OnRecord 事件。这个事件在传感器主动上报数据时触发,是最理想的数据来源。

    你可以构建一个经典的"生产者-消费者"模型:

  2. 生产者 (OnRecord 事件):在事件回调中,将传感器数据放入一个线程安全的队列(如 System.Collections.Concurrent.BlockingCollection)。

  3. 消费者 (后台任务):后台任务不再使用 Task.Delay,而是持续从队列中取出数据,然后存入你的 _accelerationBuffer 环形缓冲。

    这样做的好处:

    ● 不错过任何数据:只要数据上报,就能被捕获。

    ● 效率极高:没有数据时,后台任务处于等待状态,不消耗 CPU。

    ● 实时性最佳:数据一到就被处理。

  4. 图表绘制:用"滑动窗口"代替"完全重绘"

    问题:

    UpdateChartData 方法每次都调用 Points.Clear() 来清空所有数据点,然后重新添加。即使只显示 100 个点,这种操作也会导致图表闪烁,并且在数据更新频繁时消耗大量资源。

    改进方案:

    实现一个"滑动窗口"式的更新。

  5. 向图表系列(Series)中添加新数据点。

  6. 检查当前点的数量是否超过 MaxDataPoints。

  7. 如果超过,就移除最老的一个数据点 (Points.RemoveAt(0))。

    这样,图表每次只进行最小化的重绘,动画效果会非常平滑流畅。

    C#

    // 示例:滑动更新图表

    private void AddDataPointToChart(AccelerationData data)

    {

    // ...

    var seriesX = chart1.Series"AccX";

    seriesX.Points.AddXY(data.Timestamp.ToOADate(), data.AccX);

    // 如果点数超过上限,移除最旧的点

    if (seriesX.Points.Count > MaxDataPoints)

    {

    seriesX.Points.RemoveAt(0);

    }

    // ... 对 AccY 和 AccZ 执行相同操作

    // 相应地调整X轴的视图范围

    chart1.ChartAreas0.AxisX.Minimum = seriesX.Points0.XValue;

    chart1.ChartAreas0.AxisX.Maximum = data.Timestamp.ToOADate();

    }

    软件架构优化(提升可维护性)

  8. 类的职责分离(Refactoring)

    问题:

    Form2 这个类承担了太多的责任,它既是 UI 界面,又是蓝牙管理器,还是数据处理器和图表控制器。这使得这个文件非常庞大(超过1500行),难以维护和扩展。

    改进方案:

    将不同的功能模块拆分到独立的类中,遵循"单一职责原则"。

    ● DeviceService.cs: 专门负责蓝牙设备的扫描、连接、数据接收和指令发送。Form 通过调用它来管理设备,并通过事件来接收数据。

    ● ChartController.cs: 专门负责 chart1 的所有操作,如图表初始化、数据更新、样式设置等。

    ● DataRepository.cs: 专门负责 _accelerationBuffer 的管理,如数据存入、读取、清空、导出等。

    这样做的好处:

    ● 代码清晰:Form2.cs 会变得非常简洁,主要负责响应用户操作,并将任务委托给其他类。

    ● 易于维护:修改蓝牙逻辑时,你只需要看 DeviceService.cs 文件。

    ● 可复用和测试:这些独立的业务类可以在其他项目中复用,并且可以单独进行单元测试。

    功能与体验优化(锦上添花)

  9. 支持多设备连接与切换

    问题:

    当前应用在找到第一个符合条件的设备后就停止扫描并进行连接。如果周围有多个传感器,用户无法选择。

    改进方案:

    ● 在 UI 上添加一个 ListBox 或 ComboBox。

    ● 扫描时,将所有找到的设备都添加到这个列表中。

    ● 允许用户从列表中选择一个或多个设备进行连接。

    ● 如果连接了多个设备,可以提供一个下拉框让用户切换图表所显示的数据源。

  10. 耗时操作异步化

    问题:

    exportButton_Click 中的数据导出是同步执行的。如果历史数据非常多,写入文件时会造成 UI 线程阻塞,导致程序"未响应"。

    改进方案:

    将文件写入的核心逻辑放到 Task.Run 中执行,并使用 async/await 来等待它完成,避免冻结界面。

    C#

    private async void exportButton_Click(object sender, EventArgs e)

    {

    // ... 获取文件路径等 ...

    try

    {

    exportButton.Enabled = false; // 禁用按钮,防止重复点击

    ShowStatusMessage("正在导出...", MessageType.Info);

    复制代码
     await Task.Run(() => 
     {
         // 将耗时的文件写入操作放在这里
         File.WriteAllLines(filePath, dataLines); 
     });
    
     ShowStatusMessage("导出成功!", MessageType.Success);

    }

    catch (Exception ex)

    {

    ShowErrorMessage("导出失败", ex);

    }

    finally

    {

    exportButton.Enabled = true; // 恢复按钮

    }

    }

    总结

    总的来说,你的代码基础非常好。如果你希望它能更上一层楼,我强烈建议你:

  11. 首要任务:将数据采集方式从轮询改为事件驱动,并优化图表的更新逻辑。这两项改动对性能的提升是立竿见影的。

  12. 长期考虑:进行代码重构,将功能拆分到不同的类中。这会让你的项目在未来更容易维护和添加新功能。

    希望这些建议对你有所帮助!

相关推荐
通信小呆呆13 天前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
H__Rick14 天前
自动对焦学习-3
人工智能·学习·计算机视觉
Daisy Lee14 天前
量化学习-第1章-什么是量化金融
学习·金融·datawhale
Alsn8614 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
YM52e14 天前
买菜计算器小应用 - HarmonyOS ArkUI 开发实战-PC版本
学习·华为·harmonyos·鸿蒙·鸿蒙系统
小雨下雨的雨14 天前
HarmonyOS ArkUI训练营入门-组件掌握系列-Animation 动画效果实现-PC版本
学习·华为·harmonyos·鸿蒙
cqbzcsq14 天前
CellFlow虚拟细胞论文阅读
论文阅读·人工智能·笔记·学习·生物信息
YangYang9YangYan14 天前
2026初入职场学习数据分析的价值
学习·数据挖掘·数据分析
guslegend14 天前
理论学习:什么是 Coding Agent?
学习
自传.14 天前
尚硅谷 Vibe Coding|第三章(1) Claude Code深度使用与进阶技巧 学习笔记
笔记·学习·尚硅谷·vibecoding