Как зарегистрировать обработчик событий в c#? - PullRequest
0 голосов
/ 29 мая 2020

Я работаю над приложением windows настольного компьютера с низким энергопотреблением Bluetooth для настраиваемой службы bluetooth. Устройство, отправляющее данные, было протестировано с Android приложениями. Сейчас я работаю над библиотекой windows в C# для приема сообщений с устройства. Служба микроконтроллера основана на службе Atmel CS C. Микроконтроллер использует службу уведомлений для установления sh последовательного чата между клиентом и сервером.

Мое приложение всегда вылетает с exit code -1073740791 (0xc0000409). Этот код выхода вызван переполнением стека (STATUS_STACK_BUFFER_OVERRUN (0xc0000409)). Это связано с исключением /gs. Приложение получает данные за несколько секунд, прежде чем произойдет сбой (~ 5-30 секунд?).

Эта проблема возникает, когда я регистрирую обработчик событий для службы уведомлений Bluetooth GATT.

characteristic.ValueChanged += CharacteristicValueChangedRequested;

Обработчик событий выглядит так:

        private void CharacteristicValueChangedRequested(GattCharacteristic sender, GattValueChangedEventArgs args)
    {
        //GattNotifyCharacteristic_sender.ValueChanged -= CharacteristicValueChangedRequested_Async;
        if (args.CharacteristicValue != null)
        {
            var length = args.CharacteristicValue.Length;
            if (length > 0)
            {
                if (length < 120)
                {
                    var reader = DataReader.FromBuffer(args.CharacteristicValue);
                    LatestClientMessage = reader.ReadString(length);
                    ClientMessages.Add(LatestClientMessage);
                }
            }
        }
        //GattNotifyCharacteristic_sender.ValueChanged += CharacteristicValueChangedRequested_Async;
    }

Если я не зарегистрирую обработчик событий для полученных сообщений, приложение будет стабильным. Если я зарегистрирую пустой обработчик событий без кода, приложение также выйдет из строя с тем же кодом выхода. Постараюсь получать около 100 уведомлений в секунду. Приложение станет немного более стабильным, если я попытаюсь получать меньше данных.

Я пробовал разные методы для регистрации обработчика событий, но мне кажется, что мне нужно как-то управлять одним и тем же обработчиком событий, вызываемым несколько раз.

Я также попытался отменить регистрацию обработчика событий сразу после вызова и перерегистрировать по завершении, но это не очень помогает.

Characteristi c имеет тип GattCharacteristi c

GattCharacteristic
using Windows.Devices.Bluetooth.GenericAttributeProfile;

Регистрация в службе уведомлений выполняется по следующему коду:

        /// <summary>
    /// Register for Notification at BLE Device
    /// </summary>
    /// <param name="address"></param>
    /// <param name="Msg"></param>
    public async Task<string> RegisterNotificationForced_Async(ulong address)
    {
        var device = await BluetoothLEDevice.FromBluetoothAddressAsync(address);
        var mGattDeviceServicesResult = await device.GetGattServicesAsync();
        GattCommunicationStatus result = GattCommunicationStatus.Unreachable;

        foreach (var service in mGattDeviceServicesResult.Services)
        {
            if (service.Uuid == mGuid) //Atmel CSC Service
            {
                var mGattCharacteristicsResult = await service.GetCharacteristicsAsync(); //Characteristic on BLE Device
                if (mGattCharacteristicsResult.Status == GattCommunicationStatus.Success)
                {
                    var characteristics = mGattCharacteristicsResult.Characteristics;
                    foreach (var characteristic in characteristics)
                    {
                        if (characteristic.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Notify))
                        {
                            characteristic.ValueChanged += CharacteristicValueChangedRequested;

                            GattClientCharacteristicConfigurationDescriptorValue DescriptorVal;
                            DescriptorVal = GattClientCharacteristicConfigurationDescriptorValue.Notify;
                            result = await characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(DescriptorVal);
                            if (result != GattCommunicationStatus.Success)
                            {
                                throw new System.ArgumentException("Failed to register notification at BLE Device");
                            }
                        }
                    }
                }
                else
                {
                    throw new System.ArgumentException("Characteristics on BLE device not found");
                }
            }
        }
        return $"{result}";
    }

Проблема может быть связана с драйвером windows bluetooth и зарегистрированным там обработчиком событий ... .

Спасибо за комментарии ...

1 Ответ

0 голосов
/ 09 июня 2020

Мне не удалось найти проблему, связанную с проблемой. Проблема не возникает при использовании пакета nuget microsoft.netcore.universalwindowsplatform. По крайней мере, я нашел обходной путь. Раньше я использовал Microsoft. Windows .SDK Contracts. Новый код основан на следующем примере:

https://docs.microsoft.com/en-us/samples/microsoft/windows-universal-samples/bluetoothle/

...