首页 新闻 会员 周边 捐助

DeviceWatcher 在多线程中无法起到作用

0
悬赏园豆:5 [待解决问题]

我想做的是监控蓝牙的状态,如果有新接入的蓝牙设备的话,想第一时间加入或者更新deviceInformationDict 但是现在不管蓝牙连接或者断开,都不会更新,是什么原因造成的,感谢。


public ConcurrentDictionary<string, DeviceInformation> DeviceInformationDict = new ConcurrentDictionary<string, DeviceInformation>();

//蓝牙相关
ConcurrentDictionary<string, DeviceInformation> deviceInformationDict = TestCEF.BlueTooth.Service.DeviceManager.Instance.DeviceInformationDict;
string aqsFilter = "(System.Devices.Aep.ProtocolId:="{bb7bb05e-5972-42b5-94fc-76eaa7084d49}" OR System.Devices.Aep.ProtocolId:="{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}")" +
" AND (System.Devices.Aep.IsConnected:=System.StructuredQueryType.Boolean#True)"; //2种蓝牙设备都列出来

        string[] bleAdditionalProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.Bluetooth.Le.IsConnectable", "System.Devices.Aep.IsConnected" };

        DeviceWatcher watcher = DeviceInformation.CreateWatcher(aqsFilter, bleAdditionalProperties, DeviceInformationKind.AssociationEndpoint);
        watcher.Added += (DeviceWatcher deviceWatcher, DeviceInformation devInfo) =>
        {
            if (!String.IsNullOrWhiteSpace(devInfo.Name) && devInfo.Pairing.IsPaired)
            {
                deviceInformationDict.AddOrUpdate(devInfo.Id, devInfo, (k, v) => devInfo);
            }
        };

        watcher.Updated += (_, __) => { };

        
        watcher.Updated += HandleDeviceUpdated();
        watcher.EnumerationCompleted += (DeviceWatcher deviceWatcher, object arg) => { deviceWatcher.Stop(); };
        watcher.Stopped += (DeviceWatcher deviceWatcher, object arg) => { deviceWatcher.Start(); };
        watcher.Start();
小张.NET的主页 小张.NET | 初学一级 | 园豆:152
提问于:2023-06-05 09:40
< >
分享
所有回答(2)
0

你的问题可能是因为你没有在添加和更新事件的代码中进行线程同步。更具体地说,你正在使用两个不同的线程访问deviceInformationDict并且没有对其进行同步。这可能导致在更新设备信息时出现race condition(竞争条件)。

为了解决这个问题,你可以使用lock语句或ConcurrentDictionary类提供的方法来实现线程同步。例如,你可以将以下代码添加到AddedUpdated事件处理程序中:

lock(deviceInformationDict)
{
deviceInformationDict[devInfo.Id] = devInfo;
}

这将确保在一个线程修改deviceInformationDict时不会有其他线程访问它。

或者,你可以使用ConcurrentDictionary类,它已经处理了线程同步的问题。在这种情况下,你可以将deviceInformationDict定义更改为:

public ConcurrentDictionary<string, DeviceInformation> deviceInformationDict = new ConcurrentDictionary<string, DeviceInformation>();

然后,在事件处理程序中,你可以使用以下代码来添加或更新设备信息:

deviceInformationDict.AddOrUpdate(devInfo.Id, devInfo, (key, oldValue) => devInfo);

这将确保在多个线程同时更新deviceInformationDict时不会出现问题。

lanedm | 园豆:2396 (老鸟四级) | 2023-06-05 11:02

首先先感谢你的回答,我试过了,似乎不是线程的问题,即使不放到另开的线程中,也会造成同样的问题,是不是我哪里用错了?

支持(0) 反对(0) 小张.NET | 园豆:152 (初学一级) | 2023-06-05 14:53

@小张.NET: 在你的代码中,我没有看到你处理Removed事件。如果你的设备已经连接,然后被移除了,那么你的DeviceInformationDict将不会更新。你可以在Removed事件处理程序中删除设备信息,例如:

watcher.Removed += (DeviceWatcher deviceWatcher, DeviceInformationUpdate devUpdate) =>
{
    if (deviceInformationDict.TryGetValue(devUpdate.Id, out DeviceInformation devInfo))
    {
        deviceInformationDict.TryRemove(devUpdate.Id, out _);
    }
};

此外,你的Updated事件处理程序似乎没有实现正确。你可以尝试使用以下代码:

watcher.Updated += (DeviceWatcher deviceWatcher, DeviceInformationUpdate devUpdate) =>
{
    if (deviceInformationDict.TryGetValue(devUpdate.Id, out DeviceInformation devInfo))
    {
        devInfo.Update(devUpdate);
        deviceInformationDict[devUpdate.Id] = devInfo;
    }
};

这将更新设备信息并将其保存到DeviceInformationDict中。

最后,你可以尝试在Added事件处理程序中添加一些调试输出,以确保设备信息被正确添加到DeviceInformationDict中。例如:

watcher.Added += (DeviceWatcher deviceWatcher, DeviceInformation devInfo) =>
{
    Debug.WriteLine($"Added device: {devInfo.Id}, {devInfo.Name}");
    if (!String.IsNullOrWhiteSpace(devInfo.Name) && devInfo.Pairing.IsPaired)
    {
        deviceInformationDict.AddOrUpdate(devInfo.Id, devInfo, (k, v) => devInfo);
    }
};
支持(0) 反对(0) lanedm | 园豆:2396 (老鸟四级) | 2023-06-05 16:09
0

如果你已经尝试了上述方法但仍然没有解决问题,以下是一些可能的原因和解决方法:

检查设备是否正确配对:在你的Added事件处理程序中,你使用了devInfo.Pairing.IsPaired来检查设备是否已配对。如果设备没有正确配对,它可能不会被添加到deviceInformationDict中。确保你的设备在添加时已经正确配对。

检查过滤条件:你的aqsFilter用于筛选要监视的设备。确保你的过滤条件正确,并且符合你要监视的设备类型。

检查权限:某些设备可能需要特定的权限才能被监视。确保你的应用程序具有所需的权限来访问和监视蓝牙设备。

检查事件处理程序的实现:检查你的事件处理程序是否正确实现,并且在事件发生时执行了预期的操作。你可以尝试添加调试输出或日志语句来跟踪事件的触发和处理过程,以确定是否有任何错误或逻辑问题。

如果上述方法都没有解决你的问题,你可能需要更详细地调查问题。可以尝试使用调试器来跟踪代码执行的路径,并检查变量的值以查找潜在的问题。此外,查阅相关的官方文档、示例代码或社区讨论也可能有助于解决你的问题。

Technologyforgood | 园豆:7541 (大侠五级) | 2023-06-05 21:44
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册