Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Ukázka StreamingFeeds ukazuje, jak spravovat syndikační kanály, které obsahují velký počet položek. Ukázka na serveru ukazuje, jak zpozdit vytváření jednotlivých SyndicationItem objektů v informačním kanálu až těsně před zápisem položky do síťového datového proudu.
Na straně klienta ukázka demonstruje, jak lze vlastní formátovací modul syndikačního kanálu použít ke čtení jednotlivých položek ze síťového datového proudu, aniž by byl kanál kdykoli plně načítán do paměti.
Aby bylo možné co nejlépe předvést schopnost streamování syndikačního API, tato ukázka používá poněkud nepravděpodobný scénář, ve kterém server poskytuje kanál obsahující neomezený počet položek. V tomto případě server pokračuje v generování nových položek do informačního kanálu, dokud nezomezí, že klient přečte zadaný počet položek z informačního kanálu (ve výchozím nastavení 10). Pro zjednodušení se klient i server implementují ve stejném procesu a používají sdílený ItemCounter objekt ke sledování počtu položek, které klient vytvořil. Typ ItemCounter existuje pouze pro účely povolení čistého ukončení ukázkového scénáře a není základním prvkem modelu, který je demonstrován.
Ukázka využívá iterátory jazyka Visual C# (pomocí konstruktoru klíčového yield return slova). Další informace o iterátorech najdete v tématu Používání iterátorů na webu MSDN.
Služba
Služba implementuje základní WebGetAttribute kontrakt, který se skládá z jedné operace, jak je znázorněno v následujícím kódu.
[ServiceContract]
interface IStreamingFeedService
{
[WebGet]
[OperationContract]
Atom10FeedFormatter StreamedFeed();
}
Služba implementuje tento kontrakt pomocí ItemGenerator třídy k vytvoření potenciálně nekonečného streamu SyndicationItem instancí pomocí iterátoru, jak je znázorněno v následujícím kódu.
class ItemGenerator
{
public IEnumerable<SyndicationItem> GenerateItems()
{
while (counter.GetCount() < maxItemsRead)
{
itemsReturned++;
yield return CreateNextItem();
}
}
...
}
Když implementace služby vytvoří informační kanál, použije se výstup ItemGenerator.GenerateItems() namísto kolekce položek ve vyrovnávací paměti.
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();
}
Výsledkem je, že stream položky není nikdy plně uložen do vyrovnávací paměti. Můžete sledovat toto chování tak, že nastavíte zarážku na příkaz yield return v rámci metody ItemGenerator.GenerateItems() a všimnete si, že tato zarážka je dosažena poprvé poté, co služba vrátila výsledek metody StreamedFeed().
Klient
Klient v této ukázce používá vlastní SyndicationFeedFormatter implementaci, která zpožďuje materializaci jednotlivých položek v datovém kanálu, místo aby je ukládala do operační paměti. Vlastní StreamedAtom10FeedFormatter instance se používá následujícím způsobem.
XmlReader reader = XmlReader.Create("http://localhost:8000/Service/Feeds/StreamedFeed");
StreamedAtom10FeedFormatter formatter = new StreamedAtom10FeedFormatter(counter);
SyndicationFeed feed = formatter.ReadFrom(reader);
Za normálních okolností se volání ReadFrom(XmlReader) nevrací, dokud se celý obsah informačního kanálu nepřečte ze sítě a nezaznamená do vyrovnávací paměti. Objekt StreamedAtom10FeedFormatter však přepíše ReadItems(XmlReader, SyndicationFeed, Boolean) , aby vrátil iterátor místo kolekce s vyrovnávací pamětí, jak je znázorněno v následujícím kódu.
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();
}
V důsledku toho se každá položka nepřečte ze sítě, dokud na ni není klientská aplikace připravena při procházení výsledků ReadItems(). Toto chování můžete sledovat tak, že nastavíte zarážku na yield return příkaz uvnitř StreamedAtom10FeedFormatter.DelayReadItems() a zjistíte, že je tato zarážka poprvé dosažena po dokončení volání ReadFrom().
Následující pokyny ukazují, jak sestavit a spustit ukázku. Všimněte si, že i když server přestane generovat položky po přečtení 10 položek klienta, výstup ukazuje, že klient čte výrazně více než 10 položek. Síťová vazba, kterou ukázka používá, přenáší data ve čtyřkilobajtových (KB) segmentech. Klient proto obdrží 4 kB dat položek, než bude mít možnost číst i jednu položku. Toto je normální chování (odesílání streamovaných dat HTTP v segmentech s rozumnou velikostí zvyšuje výkon).
Jak nastavit, sestavit a spustit ukázku
Ujistěte se, že jste provedli instalační proceduru One-Time pro ukázky Windows Communication Foundation.
Pokud chcete sestavit verzi C# nebo Visual Basic .NET řešení, postupujte podle pokynů v Sestavení ukázek Windows Communication Foundation.
Pokud chcete spustit ukázku v konfiguraci pro jeden počítač nebo pro více počítačů, postupujte podle pokynů v Spuštění ukázek Windows Communication Foundation.