You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 GetGattService method: 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 Uncached mode 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 GetGattServicesForUuidAsync with Cached mode 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 BluetoothLEDevice instance is being garbage-collected: Store the DiscoveredBluetoothLEDevice object 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.ConnectionStatusChanged event. 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 using statements for Bluetooth objects: Wrapping BluetoothLEDevice or GattDeviceService in a using block will dispose them immediately when the block ends. Only use using if 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:45:13