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.
The compiler marks the variable assigned the return type of this method as IObservable<IEnumerable<IDevice>>
. I am trying to access the IDevice
from the collection. 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
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 ?
Is there an alternative way of iterating through such a type that will result in names being added to the list?
CodePudding user response:
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. 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. You haven't said that in the question, so I can't answer that.
CodePudding user response:
devNames
variable is not part of your code snippet but I assume it is declared somewhere prior to this snippet execution.
The nature of Subscriptions
is that they are async
.
devices.Subscribe
executes syncronously but the code within the subscription:
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.
You can add your logic that references devNames
within the subscription as well to resolve this issue.
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
});
}
CodePudding user response:
try this out please I think it will work with you
devNames = observable.Select(t => t.Name).ToList();