使用Plugin.BLE发送两次特征值间隔过大如何优化至10-100ms
问题根源
- 原
WriteCharacteristics方法每次调用都会重复执行GetCharacteristicsAsync获取特征、StartUpdatesAsync开启通知,这两个都是BLE IO操作,本身有几百毫秒的开销,重复调用直接拉高了第二次发送的延迟 - 嵌套
ContinueWith搭配async lambda会产生Task<Task>的嵌套任务,外层代码没有等待内层任务实际完成,导致你以为写入完成时,内层的写入/通知开启操作还在执行,时序完全混乱 - 调用侧用
Thread.Sleep(10)+Wait()的写法会阻塞线程池线程,同时混合使用await、ContinueWith、Wait多种异步等待方式,额外增加了调度延迟
解决方案
核心思路是把一次性的初始化操作和高频的写入操作拆分,同时修正异步写法避免不必要的调度消耗。
第一步:预初始化BLE特征(仅在连接成功后执行一次)
不要每次写入都重复获取特征、开启通知,把这部分逻辑移到连接成功后的初始化流程中:
// 类内部定义私有字段存储可写入的特征 private ICharacteristic _writeCharacteristic; // BLE连接成功后调用一次该方法做初始化 public async Task InitAfterConnected() { var characteristics = await Service.GetCharacteristicsAsync(); _writeCharacteristic = characteristics.First(); await _writeCharacteristic.StartUpdatesAsync(); }
第二步:重构写入方法,移除冗余逻辑
只保留核心写入逻辑,用纯async/await替代嵌套ContinueWith避免嵌套任务:
public async Task WriteCharacteristics(byte value) { try { byte[] data = {value}; await _writeCharacteristic.WriteAsync(data); } catch (Exception e) { Debug.WriteLine("********* Failed to write characteristics: " + e.Message); } }
第三步:修正调用侧逻辑
用Task.Delay替代Thread.Sleep避免线程阻塞,全程用await控制时序:
// 写入两次的封装方法 public async Task SendWithDuplicate(byte value) { // 第一次发送 await ble.WriteCharacteristics(value); // 等待10ms,Task.Delay不会阻塞线程,调度更及时 await Task.Delay(10); // 第二次发送 await ble.WriteCharacteristics(value); } // 调用时直接触发即可 _ = SendWithDuplicate(value);
额外优化建议
如果你的外设支持无响应写入模式,可以把写入类型指定为WriteWithoutResponse,写入速度会进一步大幅提升,修改写入代码即可:
await _writeCharacteristic.WriteAsync(data, WriteType.WithoutResponse);
内容的提问来源于stack exchange,提问作者nszmmp
相关产品推荐
相关产品推荐

