これを行う最も簡単な方法は、まずインターフェイスをIObservablesに変換することです。これを行うには、APIに関するいくつかの前提を設定します:
- IGeoCoordinateServiceは、いったん開始されるとpositionCallbackを何度か呼び出すことがあります。
- IGeoCoordinateServiceがexceptionCallbackを呼び出すと、それは完了し、positionCallbackを再度呼び出さない。 (この仮定はIObservableコントラクトと一致するために必要です)
- IGooglePlacesServiceはsearchCallbackを1回だけ呼び出します。 (。この仮定は、私は後で行いますSelectManyするのに便利です)
そこから、あなたはその後、これらの関数を書くことができます。
public IObservable<GeoPosition<GeoCoordinate>> ToObservable(this IGeoCoordinateService service)
{
return Observable.Create((IObserver<GeoPosition<GeoCoordinate>> observer) =>
{
service.Start(observer.OnNext, observer.OnError);
//nothing to do on unsubscribe, cannot cancel run
return (() => {});
})
}
public Func<GeoCoordinate, SearchFilter, IObservable<PlaceSearchResponse>>
ToObservable(IGooglePlacesService service)
{
return (coord, filter) =>
{
return Observable.Create((IObserver<PlaceSearchResponse> observer) =>
{
service.FindLocations(coord, filter,
(value) =>
{
observer.OnNext(value);
observer.OnCompleted();
});
//nothing to do on unsubscribe, cannot cancel run
return (() => {});
})
}
}
今あなたがIObservablesにサービスを変換することができ、あなたが連鎖することができますそのような彼らは、(うまくいけば、あなたはより良い関数名を考え出すことができる):ChainServicesを呼び出すと、何もしない、IObservablesのため通常通り、あなたが実際に行うために戻っIObservableに購読を呼び出す必要があることを
public IObservable<PlaceSearchResponse> ChainServices(IGeoCoordinateService geo, IGooglePlacesService place, SearchFilter filter)
{
return from pos in geo.ToObservable()
where pos != null && pos.Coordinate != null
from placeResponsen place.ToObservable()(pos.Coordinate, filter)
select placeResponse;
}
注意を非同期呼び出し。あなたが任意のコントロールを持っている場合
APIが使用できることをいくつかのものは、:を通じて通話途中でキャンセルする
- いくつかの方法を
- 伝えるためにいくつかの方法(IObservableがサブスクライブからIDisposableをを返すことによってこれを行います)オブザーバーでOnCompletedを呼び出すことができるようにIGeoCoordinateServiceが実行されたとき(positionCallbackを複数回呼び出すと仮定した場合)
うわー、非常に徹底的に! tyvm – vidalsasoon
Jesse Libertyという本でほぼ同じシナリオが扱われています。私は次のように書いています。http://www.amazon.com/Programming-Reactive-Extensions-Jesse-Liberty/dp/1430237473/ref=sr_1_1?ie=UTF8&s= books&qid = 1310177625&sr = 8-1 –
@Paul Betts:Preordered! –