好的我还有另一个有反应性延伸的游戏,特别是wp7。
我正在考虑GeoCoordinateWatcher positon改变事件,如此
var subject = new BehaviorSubject<GeoCoordinate>(GeoCoordinate.Unknown);
var watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default) { MovementThreshold = 0 };
watcher.PositionChanged += (o, args) =>
{
var newLocation = args.Position.Location;
if ((DateTime.Now - args.Position.Timestamp.DateTime) < locationTimeout)
{
subject.OnNext(newLocation);
}
};
我这样订阅
MyLocation.StartGettingLocations()
.Subscribe(pos =>
{
// Do something with the position
PlotLine.Locations.Add(pos);
bingMap.SetView(pos, 15);
});
应用程序运行但问题是如果我在主题中放置了一个断点,订阅只发生一次.OnNext(newLocation),我看到它不断被触发。
我做错了什么?
[编辑]
好的,我可以看到出了什么问题,代码(我不仅仅是从中学习它),使用了DistinctUntilChanged()。我假设,从简单的阅读,这会停止向用户提供相同的价值?所以我正在使用它,位置跟踪,如果手机处于相同的位置,GeoCoordinate没有改变,那么将它发送给用户是毫无意义的,所以它只是阻止它吗?
答案 0 :(得分:3)
我怀疑问题已在评论中得到解答(即如果您想要位置,即使用户没有移动,也要删除DistinctUntilChanged
)。然而,这个问题有些令人烦恼 - 它使用的是Rx,但并不是特别有效。
首先,有一种更简单的方法可以将事件转换为可观察事件(这反过来又使它们更易于使用):
var watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default) { MovementThreshold = 0 };
var geo = Observable.FromEventPattern<GeoPositionChangedEventArgs<GeoCoordinate>>(
ev => watcher.PositionChanged += ev,
ev => watcher.PositionChanged -= ev)
.Select(ev => ev.EventArgs.Position);
然后,要获得更改,不需要那些命令性的代码。就这样做:
var changes = geo.Where(pos => (DateTime.Now - pos.Timestamp.DateTime) < locationTimeout)
.Select(pos => pos.Location)
.DistinctUntilChanged();
(当然,您可以删除DistinctUntilChanged
,但不在您发布的代码中。
现在您可以直接使用changes
:
changes.Subscribe(loc =>
{
PlotLine.Locations.Add(pos);
bingMap.SetView(pos, 15);
});
没有必要管理一个真正影响一系列事件的主题。只需将事件转换为Observables即可。然后因为你一直在使用Observables,所以你可以访问许多组合器,这些组合器可以让你比现在做更多的事情。