Once I am sure I have checked that System.Devices.Aep.Bluetooth.Le.IsConnectable == true I call
DiscoveredBluetoothLEDevice = await BluetoothLEDevice.FromIdAsync(DiscoveredDeviceInformation.Id);
Often this works fine and my app can subscribe to receive updates from the GATT characteristic I am after. But equally often the call to FromIdAsync fails with
Exception thrown: 'System.ArgumentException' in System.Private.CoreLib.dll
Value does not fall within the expected range.
The Id passed in is correct, and I have tried await BluetoothLEDevice.FromBluetoothAddressAsync instead with the known Bluetooth address of the device but I often get the same exception.
What underlying problem is this cryptic error is really referring to?
N.B. Following Xavier Xie's comment below
Have you tried the official code sample to see if you still face this issue?
I have. To recreate the error I place a breakpoint on line 119 in Scenario2_Client.ConnectButton_Click, i.e. the second line in
bluetoothLeDevice = await BluetoothLEDevice.FromIdAsync(rootPage.SelectedBleDeviceId);
if (bluetoothLeDevice == null)
The first time I run the sample all is good, but if I restart when I hit the breakpoint then (in the second run through) I do not reach the breakpoint because I get the error thrown on the previous line.
Are you correctly closing/disposing of the BluetoothLEDevice anywhere?
I'm certain @Martin Zikmund's comment is actually pretty much the the correct answer here.
That is you need to properly dispose of the BluetoothLEDevice object. Sometimes when you restart GC has collected sometimes it hasn't - hence the intermittent error.
To fix either use a using block, as Martin suggests, or manually ensure you have disposed of the BluetoothLEDevice and cleared any reference to it before you exit your application. e.g
using (BluetoothLEDevice btd = BluetoothLEDevice.FromIdAsync(...))
{
// btd will be disposed when out of scope...
}
Or
bluetoothLeDevice.Dispose();
bluetoothLeDevice = null;
// You can also force garbage collection
GC.Collect();
What underlying problem is this cryptic error is really referring to?
The error is cryptic but I believe it is saying that the id is invalid (out of range) because it is already in use, that is a reference to the device exists and so you can't connect again.
As an aside you get the same thing with serial ports, etc, if you don't dispose of them properly. If you restart debugging with the same device, settings, etc - maybe GC will have cleaned up and it will work - or maybe it hasn't you'll get an error because the port is in use.
The lesson is to always properly close/dispose streams, ports, devices, files, etc. The best way to do this with objects that implement IDisposable is probably via the "using" statement syntax as you don't have to remember to do anything extra.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With