0

最初は、遅延実行が予想されるLINQクエリ(EFなど)がありました。

class Provider : IProvider
{
    public IEnumerable<Any> GetSome()
    {
         yield return new Any(); // LINQ query
    }
}

しかし、現在、そのようなプロバイダーは WCF サービス (および IoC) に移行しています。

unityContainer.RegisterType<IProvider>(
    new PerResolveLifetimeManager(),
    new InjectionFactory(c => new ChannelFactory<T>("IService").CreateChannel()));

WCF 呼び出しで遅延実行を維持することは可能ですか?

4

1 に答える 1

1

これは、実際にはLadislavMrnkaへの最後のコメントに対する回答です。あなたは言う:

なるほど、「無料のドーナツ」はありません。LINQ to Anyでは、このような動作がありますが、サービスの境界を越える必要があります。つまり、データを(逆)シリアル化する必要があります。

無料ではありませんが、それでも可能です!

サーバー側では、リクエストを初期化するメソッドと結果を取得するメソッドを1つずつ提供する必要があります。

クライアント側(特に低レベルのインフラストラクチャクラスの1つ)では、列挙子でラップでき、最後に、「ビジネス」クラスは他のクラスと同じようにその列挙子を使用できます。

各アイテムに必要な要求/応答の手段で追加のオーバーヘッドが発生することについては、すでに説明しました。これにより、遅延が発生し、ネットワーク負荷が増加します。

疑似RESTfulAPIを使用したこのアプローチのサンプルは、次のようになります。

サーバ側:

  • POST http://server/api/search-specification
    本文には、検索に必要なパラメータ(開始日や終了日など)が含まれます
    。応答は、検索仕様を識別するURIになります。
  • GET http://server/api/search-specification/1/next-result
    回答は次の項目になります。

このためのコントローラーは次のようになります。

public Response PostSearchSpecification(SearchSpecification spec)
{
    int id = _searches.Max(x => x.Key) + 1; // Make thread-safe
    _searches[id] = _provider.GetSome().GetEnumerator();
    return ...;
}

public Item GetNextResult(int searchSpecId)
{
    if(_searches[searchSpecId].MoveNext())
        return _searches.Current;
    else
        return null; // or return a HTTP status code that tells the
                     // client that there are no more items.
}

確かに1つのように見えるので、これを疑似RESTful APIと呼んでいますが、遅延実行を有効にするには、仕様ごとに内部的に状態を保持する必要があります。さらにGET http://server/api/search-specification/1/next-result、べき等ではありません。
しかし、私はそれが私が意味することを示していると思います:)

クライアント側は、次のようにカプセル化します。

class Search
{
    public IEnumerable<Item> Start(params)
    {
        var client = new HttpClient(...);
        var resultsUri = client.Post(new SearchSpecification(params)).Response;
        Item item = client.Get<Item>(resultsUri);
        while(item != null)
        {
            yield return item;
            item = client.Get<Item>(resultsUri);
        }
    }
}

そして、あなたはそれをこのように使うでしょう:

var search = new Search();

foreach(var item in search.Start(...))
    // ...

このようなものを実装する方法についての生のスケッチです。

于 2013-02-06T09:10:44.750 に答える