I’m using reactive extensions in my wp7 app that I’m making and I wish to get the the current location at certain intervals (intervals are based on a user setting). For this example lets say after every 5 seconds I wish to know the current location from the GeoCoordinateWatcher.
I have read some places that I can use .Delay(5 Seconds) but wouldn’t that just delay the stream of position changes? As I am only after the current position, would .Delay(5 seconds).Last() work for what I want?
My code so far
if (LocationServices == null)
LocationServices = new GeoCoordinateWatcher(GeoPositionAccuracy.High)
{
MovementThreshold = 2
};
// Take the first ready status from the GeoCoordinateWatcher
var status = (from o in Observable.FromEvent<GeoPositionStatusChangedEventArgs> LocationServices, "StatusChanged")
where o.EventArgs.Status == GeoPositionStatus.Ready
select o);
status.Subscribe();
var pos = (from s in status
from p in Observable.FromEvent<GeoPositionChangedEventArgs<GeoCoordinate>>(LocationServices, "PositionChanged")
select p.EventArgs.Position); // Do something here to delay?
pos.Subscribe(LastPos =>
{
// Do something with LastPos
}
);
LocationServices.Start();
I’m thinking something like this would work?
var pos = (from s in status
from p in Observable.FromEvent<GeoPositionChangedEventArgs<GeoCoordinate>>(LocationServices, "PositionChanged")
select p.EventArgs.Position).Delay( var pos = (from s in status
from p in Observable.FromEvent<GeoPositionChangedEventArgs<GeoCoordinate>>(LocationServices, "PositionChanged")
select p.EventArgs.Position).TakeLast(1).Delay(new TimeSpan(0,0,5));
pos.Subscribe(Lastpos =>
{
// Do something with Lastpos
}
);;
Edit: Nope it doesn’t work
There are a few different rate limiting operators in RX.
Sampleis the closest to what you describe, but it will not generate a notification every 5 seconds if the source is not producing new notifications (in other words: Sample = “no more often than”).You should be able to get a polling effect by combining a few other operators. To start, we will need
Intervalto get the ticks andCombineLatestto do the sampling at the ticks. However, CombineLatest will output a result both on ticks and notifications from the original source. To deal with that, we can use a combination ofScan,WhereandSelect. In the end you should have something like:A few notes about the code you posted:
This makes a new subscription to the
PositionChangedevent every time the status event is triggered as ready. This will eventually cause position changes to be reported multiple times, which is probably not what you want. You probably want something more like:EDIT Upon further review, if all you want to do is poll the position every so often, there is no need to handle either event. You can simply check the properties on a timer.
If you only want the timer to run while the watcher is “Ready”, you can use the status event, but still don’t need to use the position event.