简体   繁体   English

如何在 C# 中遍历包含 IEnumerable 的 IObservable?

[英]How to loop through an IObservable containing an IEnumerable in C#?

I am trying to get a list of paired bluetooth devices using C#, the method used returns an IObservable collection containing IEnumerable objects which contain Bluetooth Device objects.我正在尝试使用 C# 获取配对蓝牙设备的列表,使用的方法返回一个 IObservable 集合,其中包含 IEnumerable 对象,其中包含蓝牙设备对象。 The compiler marks the variable assigned the return type of this method as IObservable<IEnumerable<IDevice>> .编译器将分配此方法的返回类型的变量标记为IObservable<IEnumerable<IDevice>> I am trying to access the IDevice from the collection.我正在尝试从集合中访问IDevice The documentation of the method suggests the use of a Subscribe() method to iterate through the collection but I do not know if this Subscribe() method needs some external trigger该方法的文档建议使用Subscribe()方法来遍历集合,但我不知道此Subscribe()方法是否需要一些外部触发器

List<string> devNames= new List<string>();
//I have tested the line below and it returns true so its not a permission issue
if (adapter.CanViewPairedDevices())
{
//here is my device collection variable
IObservable<IEnumerable<IDevice>> devices =adapter.GetConnectedDevices();
//here is how I try to get device names from the above collection
devices.Subscribe(deviceResult =>
       {
         foreach(var device in deviceResult){
                        devNames.Add(device.Name);
                                            }
       });
}
//devNames is still empty at this point

My list of names is empty at the end of the method call, does Subscribe need some kind of trigger ?在方法调用结束时我的名称列表为空, Subscribe是否需要某种触发器? Is there an alternative way of iterating through such a type that will result in names being added to the list?是否有另一种迭代这种类型的方法会导致将名称添加到列表中?

What you want is this:你想要的是这样的:

IList<string> devNames =
    adapter
        .GetConnectedDevices()
        .SelectMany(devices => devices.Select(device => device.Name))
        .ToList()
        .Wait();

That will block on the observable which may not be desirable, so you can also await this code and make it asynchronous.这将阻塞可能不需要的可观察对象,因此您也可以等待此代码并使其异步。 Try this:尝试这个:

IList<string> devNames = await
    adapter
        .GetConnectedDevices()
        .SelectMany(devices => devices.Select(device => device.Name))
        .ToList();

You could use .Subscribe(...) but you wouldn't populate the List<string> devNames in the subscription.您可以使用.Subscribe(...)但不会在订阅中填充List<string> devNames Using Rx, like I have above, you end up with an observable returns your IList<string> , so in the subscription you would need to know what you want to do with the list.使用 Rx,就像我上面所说的,你最终会得到一个 observable 返回你的IList<string> ,所以在订阅中你需要知道你想对列表做什么。 You haven't said that in the question, so I can't answer that.你没有在问题中这么说,所以我无法回答。

devNames variable is not part of your code snippet but I assume it is declared somewhere prior to this snippet execution. devNames变量不是您的代码片段的一部分,但我认为它是在执行此片段之前在某处声明的。

The nature of Subscriptions is that they are async . Subscriptions的本质是它们是async的。
devices.Subscribe executes syncronously but the code within the subscription: devices.Subscribe同步执行,但订阅中的代码:

foreach(var device in deviceResult)
{
    devNames.Add(device.Name);
}

will execute at a later point, meaning that synchronous code after devices.Subscribe might not be able to see the results.将在稍后执行,这意味着devices.Subscribe之后的同步代码可能无法看到结果。

You can add your logic that references devNames within the subscription as well to resolve this issue.您也可以在订阅中添加引用devNames的逻辑来解决此问题。

List<string> bNames= new List<string>();
//I have tested the line below and it returns true so its not a permission issue
if (adapter.CanViewPairedDevices())
{
    //here is my device collection variable
    var devices =adapter.GetConnectedDevices();
    //here is how I try to get device names from the above collection
    devices.Subscribe(deviceResult =>
    {
        foreach(var device in deviceResult)
        {
            devNames.Add(device.Name);
        }
        // devNames is available here
    });
}

请尝试一下,我认为它对您有用

 devNames = observable.Select(t => t.Name).ToList();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM