I am having a strange problem when changing BLE devices that provide the same functionality.
My BLE device pairs and connects fine, and gets data no problem. If I unpair it, I can then discover it, pair, connect and get the data once again.
However, if I unpair it then pair another of the same device - i.e. with the same services & characteristics, etc. then, first of all a call to DeviceInformation.FindAllAsync() (to return devices with my service) returns no results, and a call to BluetoothLEDevice.GetGattServicesAsync() hangs and never returns.
The only way I can get it going again, is to go into the TaskManager and kill the process running the "Bluetooth Support Service" (bthserv). This then restarts automatically and I can then proceed to pair & connect and once again start downloading data.
Here is my code:
int retryCount = 5; DeviceInformation deviceInfo = null; // Sometimes Windows loses track of the services! We may need to refresh them - can sometimes take a few retries. while (deviceInfo == null && retryCount-- > 0) { // after switching devices this call usually returns an empty set even though I have successfully paired the second device with the same service. var allDeviceInfos = await DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(MyServiceId)); deviceInfo = allDeviceInfos.FirstOrDefault(d => d.Name == device.DeviceInformation.Name); if (deviceInfo == null) { _logger.LogDebug("Device not found! Retrying..."); await RefreshServices(); Thread.Sleep(1000); } } ....
private async Task RefreshServices() { _logger.LogDebug("Refreshing the device's service list."); var devices = await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelector()); var myDevices = new List<DeviceInformation>(); foreach (var device in devices.Where(d => d.Name.StartsWith("MyDeviceName_"))) { var bleDevice = await BluetoothLEDevice.FromIdAsync(device.Id); // after switching devices, the application hangs on the following line and never returns a value. var services = await bleDevice.GetGattServicesAsync(); _logger.LogDebug($"Service list from {wristOx.Name}: Status: {services.Status}, count: {services.Services?.Count}"); } } You may ask why I'm calling the RefreshServices() method. This is because I have seen in the past that when I get no results from the intial FindAllAsync() doing this seems to rectify the situation though sometimes requires several retries. (I'm thinking it's refreshing some sort of cache) If there is a better way of doing this, then that would be great to hear about too!
Notes
- I have also tried with
GetGattServicesAsync(BluetoothMode.Uncached)but get the same result. - I have tried restarting my computer, but this doesn't seem to take
GetGattServicesAsync()out of its torpor! This is really odd - killing a process "fixes" it, but restarting the computer doesn't! - Even though
DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(MyServiceId))returns 0 devices, the subsequent call toDeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelector())returns some devices, including my one!
Edit
As requested I've attempted to get the bluetooth logs using WPR and the link provided by Junjie Zhu - MSFT, and I'm taking my time now to go through the 'Generic Events' graph which is the only one with any information in it. However I'm not really sure on how to match up the hang with the events in this graph and there is far too much information to paste it in here.
e.g. I've found this 'Bluetooth' section but narrowing down the right events to look at and interpreting the results is the hard part.
Interestingly though, WPA crashes every time I try to view the RadioDiagnosticTlvVerbose events... It's an ArgumentOutOfRangeException
Another edit
As requested, here are the logs from WPR. (21MB each)
Failure - this one shows when it fails - i.e. I get 0 devices from DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(MyServiceId)) then GetGattServicesAsync() hangs forever.
Success - after killing the "Bluetooth Support Service" (it auto-restarts), in this log, I still got 0 devices from DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(MyServiceId)). However, GetGattServicesAsync() returned a list of services for the device, and after two times through this loop, DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(MyServiceId)) then finally returns my device and I can connect to it.
Device and new information
- The is a Nonin WristOx BLE 3150.
- I have now tried this on three different computers, and one of them does not have this problem! My development PC is Windows 11 23H2 and this problem is seen. There is also a MS Surface Go 2 tablet with Windows 10 22H2 which also appears to have it. But I have another MS Surface Go 2 with Windows 10 21H2 where I can switch back and forth between WristOxes without any problems!
- Another possible clue: If I get my device with
BluetoothLEDevice.FromIdAsync(deviceId)orFromBluetoothAddressAsyncand check theGattServicesproperty, it lists 1 service. (It's generic service 0x1801). After thatGetGattServicesAsynchangs as previously described. However, when I kill thebthservservice, and make the same check, it lists 0 services - after that I can callGetGattServicesAsyncand it correctly returns all services on the device without hanging.

BluetoothLEDevice.GetGattServicesAsync()with the Cached option to refresh the list of services and re-initialize the services on the device.Uncachedwould refresh the list of services as it forces it to look on the device, but as I said in my post I already tried it. However I'll giveCacheda try just in case.Cacheddoesn't work either. Same result.GetGattServicesAsync()call.