bluetooth - 为什么 BluetoothLEAdvertisementWatcher 停止触发 `Received` 事件?

标签 bluetooth windows-10 bluetooth-lowenergy

使用BluetoothLEAdvertisementWatcher的WPF应用程序最终将停止接收广告数据并且似乎处于不良状态。

Windows 10 专业版 1809 内部版本 17763.292。 通过此 winmd 文件使用 Win 10 native 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);
            }
        });
    }
}

最佳答案

这似乎是 Windows 10(1809 也可能更早)中的一个已知错误,如果您运行“主动扫描”,则可能会发生该错误。

Yes your application can cause this behavior, if you're application results in the OS doing an "active scan". Are you using DeviceWatcher and if so can you share the query you're application is using?

We are also looking at mitigations on our side, we have one in the latest 19H1 release. While active scans are not recommended for extended durations if you join Windows Insiders and choose the option that contains "active development".

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

关于bluetooth - 为什么 BluetoothLEAdvertisementWatcher 停止触发 `Received` 事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54525137/

相关文章:

Android 蓝牙 socket.connect() 失败

uwp - 如何像 Windows Build 一样创建 UWP 安装程序

java - 低功耗蓝牙 - java.lang.NullPointerException

c# - Windows UWP 蓝牙 LE 设备重新连接

ios - 如何将 iOS 与 BLE 和以前版本的蓝牙连接

command-line - 来自命令行的蓝牙

android - 适用于 Android 的 Qt BLE : Cannot read value of characteristic for Custom Service

android - Android 中的蓝牙设备发现 -- startDiscovery()

Git 子模块命令在 Windows 10 上非常慢

c++ - 设置特定于音频端点设备的应用程序(以编程方式)