如何在c#中安全注册事件处理程序?

问题描述 投票:0回答:1

我正在为定制的蓝牙服务开发蓝牙低能耗桌面Windows应用程序。发送数据的设备已使用Android应用程序进行了测试。现在,我正在使用C#开发Windows库,以接收来自设备的消息。微控制器上的服务基于Atmel CSC服务。微控制器使用通知服务在客户端和服务器之间建立串行聊天。

我的应用程序总是以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条通知。如果我尝试接收较少的数据,则该应用程序会更稳定。

我将尝试使用不同的方法来注册事件处理程序,但我认为我需要以某种方式管理多次被调用的同一事件处理程序。

我还试图在调用时立即注销事件处理程序,并在完成时重新注册事件,但这没有太大帮助。

特征是类型GattCharacteristic

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蓝牙驱动程序和在那里注册的事件处理程序有关。...

谢谢您的评论...

c# windows events bluetooth-lowenergy handler
1个回答
0
投票

我无法真正找到与该问题有关的问题。使用nuget包microsoft.netcore.universalwindowsplatform时不存在此问题。至少我找到了解决方法。在使用Microsoft.Windows.SDK合同之前。新代码基于以下示例:

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

© www.soinside.com 2019 - 2024. All rights reserved.