3

作業中の Silverlight 4 アプリで Rx 拡張機能を使用する方法を学んでいます。プロセスを特定するためにサンプルアプリを作成しましたが、何も返すことができません。メインコードは次のとおりです。

    private IObservable<Location> GetGPSCoordinates(string Address1)
    {
        var gsc = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService") as IGeocodeService;

        Location returnLocation = new Location();
        GeocodeResponse gcResp = new GeocodeResponse();

        GeocodeRequest gcr = new GeocodeRequest();
        gcr.Credentials = new Credentials();
        gcr.Credentials.ApplicationId = APP_ID2;
        gcr.Query = Address1;

        var myFunc = Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>(gsc.BeginGeocode, gsc.EndGeocode);
        gcResp = myFunc(gcr) as GeocodeResponse;

        if (gcResp.Results.Count > 0 && gcResp.Results[0].Locations.Count > 0)
        {
            returnLocation = gcResp.Results[0].Locations[0];
        }
        return returnLocation as IObservable<Location>;
    }

gcResp は null として返されます。ご意見やご提案をいただければ幸いです。

4

3 に答える 3

1

サブスクライブしている監視可能なソースは非同期であるため、サブスクライブした直後に結果にアクセスすることはできません。サブスクリプションで結果にアクセスする必要があります。

さらに良いことに、まったくサブスクライブせずに、単に応答を作成します。

private IObservable<Location> GetGPSCoordinates(string Address1)
{
    IGeocodeService gsc = 
        new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");

    Location returnLocation = new Location();
    GeocodeResponse gcResp  = new GeocodeResponse();

    GeocodeRequest gcr = new GeocodeRequest();
    gcr.Credentials = new Credentials();
    gcr.Credentials.ApplicationId = APP_ID2;
    gcr.Query = Address1;

    var factory = Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>(
        gsc.BeginGeocode, gsc.EndGeocode);

    return factory(gcr)
        .Where(response => response.Results.Count > 0 && 
                           response.Results[0].Locations.Count > 0)
        .Select(response => response.Results[0].Locations[0]);
}

最初の有効な値のみが必要な場合 (住所の場所が変更される可能性はほとんどありません)、 と の間に を追加し.Take(1)ます。WhereSelect

編集:見つからないアドレスを具体的に処理したい場合は、結果を返して消費者に処理させるかOnError、サブスクライブ時に例外を返してハンドラーを提供することができます。後者を考えている場合は、次を使用しますSelectMany

return factory(gcr)
    .SelectMany(response => (response.Results.Count > 0 && 
        response.Results[0].Locations.Count > 0)
        ? Observable.Return(response.Results[0].Locations[0])
        : Observable.Throw<Location>(new AddressNotFoundException())
    );
于 2011-03-17T07:23:37.197 に答える
0

タイプを展開すると、myFuncそれがであることがわかりますFunc<GeocodeRequest, IObservable<GeocodeResponse>>

Func<GeocodeRequest, IObservable<GeocodeResponse>> myFunc =
    Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>
        (gsc.BeginGeocode, gsc.EndGeocode);

したがって、電話をかけるmyFunc(gcr)IObservable<GeocodeResponse>、ではなくがありGeocodeResponseます。キャストが無効であるため、コードmyFunc(gcr) as GeocodeResponseが返されます。null

あなたがする必要があるのは、オブザーバブルの最後の値を取得するか、単にサブスクライブすることです。呼び出し.Last()はブロックされます。電話をかけると.Subscribe(...)、コールバックスレッドで応答が届きます。

これを試して:

gcResp = myFunc(gcr).Last();

どうやって行くのか教えてください。

于 2011-03-17T01:11:35.223 に答える
0

リチャード(およびその他)、

そのため、場所を返すコードがあり、呼び出しコードがサブスクライブしています。これが(願わくば)最終号です。GetGPSCoordinates を呼び出すと、サブスクライブが終了するのを待たずに次のステートメントがすぐに実行されます。ボタンの OnClick イベント ハンドラの例を次に示します。

Location newLoc = new Location();

GetGPSCoordinates(this.Input.Text).ObserveOnDispatcher().Subscribe(x =>
            {
             if (x.Results.Count > 0 && x.Results[0].Locations.Count > 0)
                  {
                     newLoc = x.Results[0].Locations[0];
                     Output.Text = "Latitude: " + newLoc.Latitude.ToString() +
  ", Longtude: " + newLoc.Longitude.ToString();
                  }
             else
                  {
                    Output.Text = "Invalid address";
                  }
});
            Output.Text = " Outside of subscribe --- Latitude: " + newLoc.Latitude.ToString() +
  ", Longtude: " + newLoc.Longitude.ToString();

サブスクライブの外部で行われる Output.Text 割り当ては、サブスクライブが完了する前に実行され、ゼロが表示され、サブスクライブ内の割り当てが新しい場所情報を表示します。

このプロセスの目的は、データベース レコードに保存される位置情報を取得することです。Foreach ループで複数のアドレスを順番に処理しています。コーディング トラップとしての非同期コールバックの問題を回避するための解決策として、Rx 拡張機能を選択しました。しかし、私はあるトラップを別のトラップに交換したようです.

ご意見、ご感想、ご提案はありますか?

于 2011-03-17T19:27:18.187 に答える