为什么BluetoothLEAdvertisementWatcher停止触发“已接收”事件?

时间:2019-02-04 22:16:09

标签: bluetooth windows-10 bluetooth-lowenergy

使用BluetoothLEAdvertisementWatcher的WPF应用最终将停止接收广告数据,并且状态似乎不正确。

Windows 10 Pro 1809内部版本17763.292。 通过以下winmd文件使用Win 10本机api的WPF应用:C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.17763.0\Windows.winmd

触发不良状态需要1到7个小时,但最终总会发生。

进入不良状态后,“系统”进程显示CPU使用率很高。

在树莓派上找到了似乎描述相同行为的东西:https://github.com/MicrosoftDocs/windows-uwp/issues/812

此仓库可复制:https://github.com/jeremywho/win10testingAdWatcher

以下是BluetoothLEAdvertisementWatcher周围的代码:

public class MainWindowViewModel : BaseViewModel
{
    public ObservableCollection<DeviceViewModel> Devices { get; } = new ObservableCollection<DeviceViewModel>();
    private readonly BluetoothLEAdvertisementWatcher _watcher;
    private object _locker = new object();

    public MainWindowViewModel()
    {
        _watcher = new BluetoothLEAdvertisementWatcher {ScanningMode = BluetoothLEScanningMode.Active};
        _watcher.Received += OnAdvertisementReceived;
        _watcher.Stopped += OnAdvertisementWatcherStopped;

        _watcher.Start();
    }

    private void OnAdvertisementWatcherStopped(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementWatcherStoppedEventArgs args)
    {
        Debug.WriteLine($"{DateTime.Now} [{sender.Status}] [{sender.GetHashCode()}] stopped called");
    }

    private void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
    {
        if (string.IsNullOrEmpty(eventArgs.Advertisement.LocalName)) return;

        var timestamp = eventArgs.Timestamp;
        var advertisementType = eventArgs.AdvertisementType;
        var rssi = eventArgs.RawSignalStrengthInDBm;
        var localName = eventArgs.Advertisement.LocalName;

        Debug.WriteLine($"[{DateTime.Now}] [{timestamp}] [{localName}] [{rssi}] [{advertisementType}]");

        lock(_locker)
        {
            var foundDevice = Devices.FirstOrDefault(d => d.BluetoothAddress == eventArgs.BluetoothAddress.ToString());
            if (foundDevice != null)
            {
                foundDevice.LastSeen = timestamp.ToString();
                return;
            }
        }

        Application.Current.Dispatcher.Invoke(() =>
        {
            lock (_locker)
            {
                var device = new DeviceViewModel(eventArgs.Advertisement.LocalName, eventArgs.BluetoothAddress, timestamp);
                Devices.Add(device);
            }
        });
    }
}

1 个答案:

答案 0 :(得分:1)

如果运行“主动扫描”,这似乎是Windows 10中的一个已知错误(也许是1809年或更早)。

  

是的,如果您的应用程序导致操作系统执行“主动扫描”,则您的应用程序可能会导致此行为。您正在使用DeviceWatcher,如果可以,则可以共享您正在使用的应用程序查询吗?

     

我们也在研究缓解问题,我们在最新的19H1版本中提供了缓解措施。如果您加入Windows Insiders并选择包含“主动开发”的选项,则不建议您长时间进行主动扫描。

https://social.msdn.microsoft.com/Forums/en-US/274e5d96-d21d-490d-8c8b-934a41239f88/windows-100177631-microsoftbluetoothlegacyleenumeratorsys-stuck-in-its-deviced0entry-routine?forum=wdk