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

Xamarin应用INotifyPropertyChanged重新订阅失效仅首次生效问题

Xamarin蓝牙重连后事件订阅失效解决方案
  • 优先确认实例一致性
    每次重连前后分别打印ble.Adapter、ble、data三个对象的哈希值(调用GetHashCode()方法),对比首次启动和重连后的哈希值:如果不一致,说明你的重连逻辑中生成了新的实例,你现有代码中的-=操作是在旧实例上执行,新实例根本没有绑定对应的事件处理方法,自然不会触发回调。
  • 调整订阅逻辑执行时机
    不要将订阅逻辑放在if (ble.GetConnectionStatus())的连接成功判断分支内,把订阅逻辑提前到初始化ble适配器、初始化data对象之后,执行蓝牙连接操作之前,避免连接成功后才订阅漏掉中间事件,也避免实例更新后没有同步绑定订阅。
  • 优化订阅清理逻辑
    新增全局变量保存上一次绑定的实例引用,每次更换实例、重新订阅前先清理旧实例的订阅,避免旧订阅残留,示例代码:
    // 全局变量保存上次绑定的实例引用
    private IAdapter _oldAdapter;
    private IBle _oldBle;
    private IData _oldData;
    
    // 订阅前先清理旧实例
    if (_oldAdapter != null)
    {
        _oldAdapter.DeviceConnectionLost -= Adapter_DeviceConnectionLost;
    }
    if (_oldBle != null)
    {
        _oldBle.PropertyChanged -= Ble_PropertyChanged;
    }
    if (_oldData != null)
    {
        _oldData.PropertyChanged -= data_PropertyChanged;
    }
    
    // 给当前实例绑定订阅
    ble.Adapter.DeviceConnectionLost += Adapter_DeviceConnectionLost;
    ble.PropertyChanged += Ble_PropertyChanged;
    data.PropertyChanged += data_PropertyChanged;
    
    // 更新保存的实例引用
    _oldAdapter = ble.Adapter;
    _oldBle = ble;
    _oldData = data;
    
  • 保证线程一致性
    现有代码中用Device.BeginInvokeOnMainThread切换到主线程操作订阅是正确的,要确保所有订阅、取消订阅操作都在同一个线程执行,如果有后台线程操作事件订阅的场景,也会出现订阅静默失效的问题。
  • 改用弱事件模式规避引用残留
    如果上述方案都无效,可以改用Xamarin官方提供的WeakEventManager弱事件管理器来订阅事件,避免事件订阅持有实例引用导致旧实例无法释放,也能彻底解决订阅残留导致的失效问题,示例写法:
    // 订阅事件
    WeakEventManager<IAdapter, EventArgs>.AddHandler(
        ble.Adapter, 
        nameof(ble.Adapter.DeviceConnectionLost), 
        Adapter_DeviceConnectionLost);
    
    // 取消订阅事件
    WeakEventManager<IAdapter, EventArgs>.RemoveHandler(
        ble.Adapter, 
        nameof(ble.Adapter.DeviceConnectionLost), 
        Adapter_DeviceConnectionLost);
    

内容的提问来源于stack exchange,提问作者nszmmp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 15:54:06