0

これは掲示板での最初の質問です。私は、WCF と MVVM パターンを使用して、初めてのエンタープライズ向けの Silverlight (5) アプリケーションを作成しています。私の問題は、モデル クラスで WCF サービスを呼び出す方法を理解していないことです (ここに問題があります) 。呼び出し元のビュー モデルに結果を返す前に、結果を待ちます。

async および await キーワードの使用法について msdn を調べましたが、どのメソッドを "async" としてマークする必要があるかわかりませんでした。サービスの自動生成された Reference.cs ファイルを変更する必要があるように思えましたが、私には疑問があります。もっと基本的には、WCF を使用することで期待どおりに動作するはずなので、async と await を使用する必要があるかどうかさえわかりません。

とにかく、ここに私が持っているモデルクラスがあります。WCF 呼び出しの完了後に return ステートメントが実行されることを期待していますが、そうではありません。

public class CRMModel
{
    ObservableCollection<CarrierInfo> carrierInfoCollection = new ObservableCollection<CarrierInfo>();

    public ObservableCollection<CarrierInfo> GetCarrierInformation()
    {
        var client = new CarrierRateService.CarrierRateServiceClient();
        client.GetCarrierInformationCompleted += (s, e) =>
        {
            var info = e.Result;
            carrierInfoCollection = info;
            System.Diagnostics.Debug.WriteLine("Just got the result set: " + carrierInfoCollection.Count);

        };

        client.GetCarrierInformationAsync();

        System.Diagnostics.Debug.WriteLine("About to return with: " + carrierInfoCollection.Count);
        return carrierInfoCollection;
    }
}

おそらくご想像のとおり、結果は次のとおりです。

戻る予定: 0

結果セットを取得しました: 3

助けてくれてどうもありがとう!フランシス

4

2 に答える 2

3

SOへようこそ!

まず、Silverlight 5 を有効asyncにするには、 Microsoft.Bcl.Async パッケージ(現在はベータ版)awaitをインストールする必要があります。

await次に、WCF プロキシ ジェネレーターが互換性のある非同期メソッドを生成しなかったという事実に対処する必要があります。これを修正する最も簡単な方法は、Visual Studio 2012 の [サービス参照の追加] ダイアログで適切なボックスをオンにすることです。ただし、これが Silverlight で機能するかどうかは 100% 確信が持てませTaskCompletionSourceasync

完全なサンプルコードは次のとおりです。

public static Task<ObservableCollection<CarrierInfo>> GetCarrierInformationTaskAsync(this CarrierRateService.CarrierRateServiceClient @this)
{
    var tcs = new TaskCompletionSource<ObservableCollection<CarrierInfo>>();

    @this.GetCarrierInformationCompleted += (s,e) =>
    {
        if (e.Error != null) tcs.TrySetException(e.Error);
        else if (e.Cancelled) tcs.TrySetCanceled();
        else tcs.TrySetResult(e.Result);
    };
    @this.GetCarrierInformationAsync(url);
    return tcs.Task;
}

次のコードを使用して待機できます。

public ObservableCollection<CarrierInfo> GetCarrierInformation()
{
    var client = new CarrierRateService.CarrierRateServiceClient();
    carrierInfoCollection = await client.GetCarrierInformationTaskAsync();
    System.Diagnostics.Debug.WriteLine("Just got the result set: " + carrierInfoCollection.Count);

    System.Diagnostics.Debug.WriteLine("About to return with: " + carrierInfoCollection.Count);
    return carrierInfoCollection;
}
于 2013-01-07T17:34:36.763 に答える
0

Stpehen と Toni さん、ご提案ありがとうございます。この記事で概説されているアプローチを使用するまで、私はまだ苦労していました.VMはモデルにコールバックメソッドを渡します.モデルは、このメソッドを牽引してWCFサービスを呼び出すだけです.

モデルの無名関数で最初にロジックを指定したとき、非同期性によるタイミングの問題に遭遇しました。

私はメインフレームのバックグラウンドを持っているので、.NET でのこのような単純なことは、私にとってまだ目新しいものです。:)

于 2013-01-10T15:58:40.150 に答える