dotnet-bluetooth-le / dotnet-bluetooth-le

Bluetooth LE plugin for Xamarin/MAUI, supporting Android, iOS, Mac, Windows
Apache License 2.0
801 stars 308 forks source link

WinUI Call to `DisconnectDeviceAsync` may not complete. #850

Open axa88 opened 1 month ago

axa88 commented 1 month ago

Call to DisconnectDeviceAsync may never complete. The call doesn't take a CancelationToken, perhaps it should.

It might take several Connect/Disconnect cycles, but eventually DisconnectDeviceAsync will hang.

Hadn't noticed this behavior in v3.0.0, nor on Android

Steps to reproduce

  1. Connect/Disconnect

  2. Observe eventually a call to DisconnectDeviceAsync will not complete

Expected behavior

the call completes

Actual behavior

it doesn't complete

Crashlog

none

Configuration

Version of the Plugin: 3.1 rc1

Platform: image

Device:

Processor   Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz   1.80 GHz
Device ID   2F7EBCF5-2024-4778-9E85-988D5FD862D6
System type 64-bit operating system, x64-based processor

Intel Dual Band Wireless-AC 8265, Wi-Fi 2x2 802.11ac + **Bluetooth 4.1**, M.2 card
smsissuechecker commented 1 month ago

Hi @axa88,

I'm the friendly issue checker. Thanks for using the issue template :star2: I appreciate it very much. I'm sure, the maintainers of this repository will answer, soon.

axa88 commented 1 month ago

Hmm I see this issue has some history perhaps #788

AskBojesen commented 1 month ago

Hmm I see this issue has some history perhaps #788

Yes I agree #788 is the same... It is quite annoying Windows API doesn't have a disconnect method. In my desktop app I actually turn on / off the Bluotooth - and that works as a workaround. Turning Bluetooth off disconnects :-)

I can give it yet another shot before next release.

axa88 commented 1 month ago

@AskBojesen I can imagine how a lack of Disconnect functionality could be problematic here... that seems fundamentally flawed.

During initial observations of this issue, I note a that after DisconnectDeviceAsync failure, IDevice.NativeDevice is then null and thus unusable.

My current workaround is basically appending DisconnectDeviceAsync with WaitAsync which takes a CancellationToken. Then ignoring any IDevice that is found having NativeDevice = null, but this is be brittle.

Unfortunately as a symptom this now unusable device is left in the library cache if you will, and nothing, not even toggling Bluetooth on/off, will remove it. It cant be reacquired/replaced and the result is a catastrophic state.

Hopefully you find a solution. Perhaps that includes overloading DisconnectDeviceAsync to take a CancellationToken and return Task<bool> : success or not

axa88 commented 4 weeks ago

@AskBojesen

In my desktop app I actually turn on / off the Bluotooth - and that works as a workaround. Turning Bluetooth off disconnects :-)

This doesn't work for me, might you be able to provide any other info/advice to recover from this state?

If you hadn't found these references already: This SO post looks informative. There's also this post