2011-07-08 15 views
0

を返す2つの非同期メソッドの結果を見て、私はアクションのコールバックnoobの質問 - アクション<T>

public interface IGeoCoordinateService 
{ 
    void Start(Action<GeoPosition<GeoCoordinate>> positionCallback, Action<Exception> exceptionCallback); 
} 

public interface IGooglePlacesService 
{ 
    void FindLocations(GeoCoordinate geoCoordinate, SearchFilter searchFilter, Action<PlaceSearchResponse> searchCallback); 
} 
  • を使用し、次の2つの非同期メソッドを持って、私は私の前にGeoCoordinateServiceから、私は結果を持っていることを確認する必要がありGooglePlacesServiceを実行します。
  • 私も毎回(nullではない)地理座標の変化のRxでこれを行うには

最も簡単な方法はGooglePlacesServiceを実行したい

  • ? (私は極端なnoobですので、Rx用語に慣れてください)

  • 答えて

    2

    これを行う最も簡単な方法は、まずインターフェイスを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を複数回呼び出すと仮定した場合)
    +0

    うわー、非常に徹底的に! tyvm – vidalsasoon

    +2

    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 –

    +0

    @Paul Betts:Preordered! –

    関連する問題