Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Sampel StreamingFeeds menunjukkan cara mengelola umpan sindikasi yang berisi sejumlah besar item. Di server, sampel menunjukkan cara menunda pembuatan objek individual SyndicationItem dalam umpan sampai segera sebelum item ditulis ke aliran jaringan.
Pada klien, sampel menunjukkan bagaimana pemformat umpan sindikasi kustom dapat digunakan untuk membaca item individual dari aliran jaringan sehingga umpan yang dibaca tidak pernah sepenuhnya di-buffer ke dalam memori.
Untuk menunjukkan kemampuan streaming API sindikasi dengan sebaik-baiknya, sampel ini menggunakan skenario yang agak tidak mungkin di mana server mengekspos umpan yang berisi jumlah item tak terbatas. Dalam hal ini, server terus menghasilkan item baru ke dalam umpan sampai menentukan bahwa klien telah membaca jumlah item tertentu dari umpan (secara default, 10). Untuk kesederhanaan, klien dan server diimplementasikan dalam proses yang sama dan menggunakan objek bersama ItemCounter untuk melacak berapa banyak item yang telah dihasilkan klien. Jenis ItemCounter hanya ada untuk tujuan memungkinkan skenario sampel berakhir dengan baik, dan bukan elemen inti dari pola yang sedang ditunjukkan.
Demonstrasi menggunakan iterator Visual C# (menggunakan yield return konstruksi kata kunci). Untuk informasi selengkapnya tentang iterator, lihat topik "Menggunakan Iterator" di MSDN.
Pelayanan
Layanan ini menerapkan kontrak dasar WebGetAttribute yang terdiri dari satu operasi, seperti yang ditunjukkan dalam kode berikut.
[ServiceContract]
interface IStreamingFeedService
{
[WebGet]
[OperationContract]
Atom10FeedFormatter StreamedFeed();
}
Layanan menerapkan kontrak ini dengan menggunakan kelas ItemGenerator untuk membuat aliran SyndicationItem instance tak terbatas menggunakan iterator, seperti pada kode berikut.
class ItemGenerator
{
public IEnumerable<SyndicationItem> GenerateItems()
{
while (counter.GetCount() < maxItemsRead)
{
itemsReturned++;
yield return CreateNextItem();
}
}
...
}
Ketika implementasi layanan membuat umpan, output ItemGenerator.GenerateItems() digunakan alih-alih kumpulan item yang di-buffer.
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();
}
Akibatnya, aliran item tidak pernah sepenuhnya di-buffer ke dalam memori. Anda dapat mengamati perilaku ini dengan mengatur titik henti pada pernyataan di yield return dalam ItemGenerator.GenerateItems() metode dan mencatat bahwa titik henti ini ditemui untuk pertama kalinya setelah layanan mengembalikan hasil StreamedFeed() metode.
Klien
Klien dalam sampel ini menggunakan implementasi kustom SyndicationFeedFormatter yang menunda proses materialisasi item individual dalam aliran data daripada menyimpannya ke dalam memori. Instans kustom StreamedAtom10FeedFormatter digunakan sebagai berikut.
XmlReader reader = XmlReader.Create("http://localhost:8000/Service/Feeds/StreamedFeed");
StreamedAtom10FeedFormatter formatter = new StreamedAtom10FeedFormatter(counter);
SyndicationFeed feed = formatter.ReadFrom(reader);
Biasanya, panggilan untuk ReadFrom(XmlReader) tidak kembali sampai seluruh isi umpan telah dibaca dari jaringan dan di-buffer ke dalam memori. Namun, StreamedAtom10FeedFormatter objek mengambil alih ReadItems(XmlReader, SyndicationFeed, Boolean) untuk mengembalikan iterator alih-alih koleksi buffer, seperti yang ditunjukkan dalam kode berikut.
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();
}
Akibatnya, setiap item tidak dibaca dari jaringan sampai aplikasi klien melalui hasil ReadItems() dan siap menggunakannya. Anda dapat mengamati perilaku ini dengan mengatur titik henti pada yield return pernyataan di dalam StreamedAtom10FeedFormatter.DelayReadItems() dan memperhatikan bahwa titik henti ini ditemui untuk pertama kalinya setelah panggilan ReadFrom() selesai.
Instruksi berikut menunjukkan cara membuat dan menjalankan sampel. Perhatikan bahwa meskipun server berhenti menghasilkan item setelah klien membaca 10 item, output menunjukkan bahwa klien membaca secara signifikan lebih dari 10 item. Ini karena pengikatan jaringan yang digunakan oleh sampel mengirimkan data dalam segmen empat kilobyte (KB). Dengan demikian, klien menerima 4KB data item sebelum memiliki kesempatan untuk membaca bahkan satu item. Ini adalah perilaku normal (mengirim data HTTP yang dialirkan dalam segmen berukuran wajar meningkatkan performa).
Untuk menyiapkan, mengompilasi, dan menjalankan sampel
Pastikan Anda telah melakukan Prosedur Penyiapan One-Time untuk Sampel Windows Communication Foundation.
Untuk membangun solusi edisi C# atau Visual Basic .NET, ikuti instruksi di Membangun Sampel Windows Communication Foundation.
Untuk menjalankan sampel dalam konfigurasi satu atau lintas komputer, ikuti instruksi di Menjalankan Sampel Windows Communication Foundation.