ストリーミング フィードのサンプル
このサンプルでは、多数の項目が含まれた配信フィードを管理する方法を示します。サーバー側のサンプルは、フィード内での個々の SyndicationItem オブジェクトの作成を、項目がネットワーク ストリームに書き込まれる直前まで遅らせる方法を示しています。
メモ : |
---|
このサンプルをビルドして実行するには、.NET Framework Version 3.5 をインストールする必要があります。Visual Studio 2008 では、プロジェクトとソリューション ファイルを開く必要があります。 |
クライアント側のサンプルは、カスタム配信フィード フォーマッタを使用して個々の項目をネットワーク ストリームから読み取り、読み取られたフィードがメモリに完全にバッファされないようにする方法を示しています。
配信 API のストリーミング機能を十分に示すため、このサンプルでは、無数の項目を含むフィードがサーバーによって公開されるという多少通常とは異なるシナリオを使用しています。この場合、サーバーは、クライアントがフィードから特定の数 (既定では 10) の項目を読み取ったと判断するまで、新しい項目をフィードに対して生成し続けます。処理を簡単にするために、クライアントとサーバーは両方とも同じプロセスで実装され、共有 ItemCounter
オブジェクトを使用して、クライアントによって生成された項目の数を追跡します。ItemCounter
型は、サンプル シナリオを正常に終了するためにのみ存在し、示されるパターンの重要な要素ではありません。
このサンプルでは、Visual C# 反復子を使用します (yield return
キーワード コンストラクトを使用)。反復子の詳細については、MSDN の「反復子の使用」を参照してください。
サービス
次のコードに示すように、サービスは、1 つの操作で構成される基本的な WebGetAttribute コントラクトを実装します。
[ServiceContract]
interface IStreamingFeedService
{
[WebGet]
[OperationContract]
Atom10FeedFormatter StreamedFeed();
}
次のコードに示すように、サービスは、ItemGenerator
クラスを使用してこのコントラクトを実装し、反復子を使用する SyndicationItem インスタンスの無数のストリームを作成します。
class ItemGenerator
{
public IEnumerable<SyndicationItem> GenerateItems()
{
while (counter.GetCount() < maxItemsRead)
{
itemsReturned++;
yield return CreateNextItem();
}
}
...
}
サービスの実装によってフィードが作成されると、項目のバッファされたコレクションの代わりに ItemGenerator.GenerateItems()
の出力が使用されます。
public Atom10FeedFormatter StreamedFeed()
{
SyndicationFeed feed = new SyndicationFeed("Streamed feed", "Feed to test streaming", null);
//Generate an infinite stream of items. Both the client and the service share
//a reference to the ItemCounter, which allows the sample to terminate
//execution after the client has read 10 items from the stream
ItemGenerator itemGenerator = new ItemGenerator(this.counter, 10);
feed.Items = itemGenerator.GenerateItems();
return feed.GetAtom10Formatter();
}
その結果、項目のストリームはメモリに完全にはバッファされません。ItemGenerator.GenerateItems()
メソッド内の yield return
ステートメントでブレークポイントを設定し、サービスによって StreamedFeed()
メソッドの結果が返されてからこのブレークポイントが検出されることに注意して、この動作を確認します。
クライアント
このサンプルのクライアントでは、フィードの項目をメモリにバッファする代わりに、個々の項目の実体化を遅延させるカスタム SyndicationFeedFormatter 実装を使用します。カスタム StreamedAtom10FeedFormatter
インスタンスの使用方法は次のとおりです。
XmlReader reader = XmlReader.Create("https://localhost:8000/Service/Feeds/StreamedFeed");
StreamedAtom10FeedFormatter formatter = new StreamedAtom10FeedFormatter(counter);
SyndicationFeed feed = formatter.ReadFrom(reader);
通常、ReadFrom の呼び出しは、フィードのコンテンツ全体がネットワークから読み取られ、メモリにバッファされるまで返されません。ただし、次のコードに示すように、StreamedAtom10FeedFormatter
オブジェクトによって ReadItems がオーバーライドされ、バッファ内のコレクションの代わりに反復子が返されます。
protected override IEnumerable<SyndicationItem> ReadItems(XmlReader reader, SyndicationFeed feed, out bool areAllItemsRead)
{
areAllItemsRead = false;
return DelayReadItems(reader, feed);
}
private IEnumerable<SyndicationItem> DelayReadItems(XmlReader reader, SyndicationFeed feed)
{
while (reader.IsStartElement("entry", "http://www.w3.org/2005/Atom"))
{
yield return this.ReadItem(reader, feed);
}
reader.ReadEndElement();
}
その結果、各項目は、ReadItems()
の結果を走査するクライアント アプリケーションで使用可能な状態になるまで、ネットワークから読み取られません。StreamedAtom10FeedFormatter.DelayReadItems()
内の yield return
ステートメントでブレークポイントを設定し、ReadFrom()
の呼び出しが完了してからこのブレークポイントが検出されることに注意して、この動作を確認します。
次の手順は、サンプルをビルドして実行する方法を示しています。クライアントが 10 個の項目を読み取った後にサーバーによる項目の生成が停止されると、クライアントが読み取った項目数は 10 個より非常に多く出力されます。これは、サンプルで使用されたネットワーキング バインディングによってデータが 4 キロバイト (KB) セグメントで転送されることが原因です。このような場合、クライアントは、項目を 1 つでも読み取る前に 4 KB の項目データを受信します。これは通常の動作です (適切にサイズが調整されたセグメントでストリーミングされた HTTP データを送信すると、パフォーマンスが向上します)。
サンプルを設定、ビルド、および実行するには
「Windows Communication Foundation サンプルの 1 回限りのセットアップの手順」が実行済みであることを確認します。
ソリューションの C# 版または Visual Basic .NET 版をビルドするには、「Windows Communication Foundation サンプルのビルド」の手順を参照してください。
単一コンピュータ構成か複数コンピュータ構成かに応じて、「Windows Communication Foundation サンプルの実行」の手順に従います。
関連項目
その他の技術情報
Copyright © 2007 by Microsoft Corporation.All rights reserved.