You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 14:45:08