UWP蓝牙O6设备连接代码优化及WriteClientCharacteristicConfigurationDescriptorAsync异常
UWP Bluetooth Optimization & ObjectDisposedException Fix for O6 Device
Let's break down your problem into two key areas: optimizing service discovery performance and resolving the System.ObjectDisposedException when writing to the client characteristic configuration descriptor.
Performance Optimization for Gatt Service Discovery
Looking at your timing data, the differences make perfect sense based on how UWP's Bluetooth API handles caching:
DiscoveredBluetoothLEDevice.GetGattService(gattServiceGuid)(20ms): This synchronous method pulls directly from the system's cached service data—it's the fastest option because it skips any over-the-air communication with the device.GetGattServicesForUuidAsync(..., BluetoothCacheMode.Uncached)(4284ms): This forces a full re-scan of the device's services via Bluetooth, which is why it's so slow. It's only necessary if you suspect the device's service list has changed dynamically.GetGattServicesForUuidAsync(..., BluetoothCacheMode.Cached)(444ms): This uses cached data but runs asynchronously (the overhead here is likely from async context switching rather than the actual service lookup).
Optimization Tips:
- Prioritize the synchronous
GetGattServicemethod: Use this whenever possible, as it's the lowest-latency way to access cached services. Just ensure the device has already been discovered and its services are cached (you can pre-cache them on initial device connection). - Avoid
Uncachedmode unless absolutely necessary: Reserve it for rare cases where you need to refresh the service list (e.g., after the device firmware updates). For regular operations, stick to cached data. - Pre-cache services upfront: When you first connect to the O6 device, call
GetGattServicesForUuidAsyncwithCachedmode once. This populates the system cache, making subsequent calls (sync or async cached) much faster.
Fixing System.ObjectDisposedException on WriteClientCharacteristicConfigurationDescriptorAsync
This exception almost always means you're trying to operate on a Bluetooth object (device, service, or characteristic) that has already been disposed by the system or your code. Here's how to fix it:
Common Causes & Solutions:
- Your
BluetoothLEDeviceinstance is being garbage-collected: Store theDiscoveredBluetoothLEDeviceobject in a class-level variable instead of a local method variable. This keeps it in scope longer and prevents accidental disposal. - Check object validity before operations: Before calling
WriteClientCharacteristicConfigurationDescriptorAsync, verify the state of your objects:if (DiscoveredBluetoothLEDevice.ConnectionStatus == BluetoothConnectionStatus.Connected && characteristic != null && characteristic.Status == GattCommunicationStatus.Success) { // Proceed with the write operation var result = await characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify); } - Handle device disconnect events: Subscribe to the
BluetoothLEDevice.ConnectionStatusChangedevent. When the device disconnects, clear any references to Gatt services/characteristics to avoid trying to use them later:DiscoveredBluetoothLEDevice.ConnectionStatusChanged += (sender, args) => { if (args.ConnectionStatus == BluetoothConnectionStatus.Disconnected) { // Clear cached service/characteristic references _cachedGattService = null; _targetCharacteristic = null; } }; - Avoid overusing
usingstatements for Bluetooth objects: WrappingBluetoothLEDeviceorGattDeviceServicein ausingblock will dispose them immediately when the block ends. Only useusingif you're done with the object permanently. - Add retry logic for transient cases: If the exception happens occasionally (e.g., temporary connection blips), implement a retry loop. Before retrying, re-fetch the service/characteristic using cached mode to ensure you have a valid reference:
int retryCount = 0; const int maxRetries = 2; GattCommunicationStatus resultStatus = GattCommunicationStatus.Unreachable; while (retryCount < maxRetries && resultStatus != GattCommunicationStatus.Success) { try { var service = DiscoveredBluetoothLEDevice.GetGattService(gattServiceGuid); var characteristic = service.GetCharacteristics(characteristicGuid).FirstOrDefault(); if (characteristic != null) { resultStatus = await characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify); } } catch (ObjectDisposedException) { retryCount++; // Wait a short moment before retrying await Task.Delay(100); } }
内容的提问来源于stack exchange,提问作者dumbledad
相关产品推荐
相关产品推荐

