Esempio trasmissione feedStreaming Feeds Sample

Questo esempio illustra come gestire feed che contengono numerosi elementi.This sample demonstrates how to manage syndication feeds that contain large numbers of items. Nel server, l'esempio illustra come rimandare la creazione di oggetti SyndicationItem singoli all'interno del feed fino a immediatamente prima della scrittura dell'elemento nel flusso della rete.On the server, the sample demonstrates how to delay the creation of individual SyndicationItem objects within the feed until immediately before the item is written to the network stream.

Sul client, l'esempio illustra come un formattatore del feed di distribuzione personalizzato possa essere utilizzato per leggere elementi singoli dal flusso della rete così che il feed letto non sia mai pienamente memorizzato nel buffer.On the client, the sample shows how a custom syndication feed formatter can be used to read individual items from the network stream so that the feed being read is never fully buffered into memory.

Per dimostrare al meglio la funzionalità del flusso di diffusione API, questo esempio utilizza uno scenario piuttosto improbabile nel quale il server espone un feed che contiene un numero infinito di elementi.To best demonstrate the streaming capability of the syndication API, this sample uses a somewhat unlikely scenario in which the server exposes a feed that contains an infinite number of items. In questo caso, il server continua a generare nuovi elementi nel feed fino a determinare che il client ha letto un numero specificato di elementi dal feed (10, per impostazione predefinita).In this case, the server continues generating new items into the feed until it determines that the client has read a specified number of items from the feed (by default, 10). Per semplicità, sia il client che il server vengono implementati nello stesso processo e utilizzano un oggetto ItemCounter condiviso per tenere traccia del numero di elementi prodotti dal client.For simplicity, both the client and the server are implemented in the same process and use a shared ItemCounter object to keep track of how many items the client has produced. Il tipo ItemCounter esiste solo allo scopo di consentire allo scenario di esempio di terminare in modo pulito e non è un elemento principale dello schema illustrato.The ItemCounter type exists only for the purpose of allowing the sample scenario to terminate cleanly, and is not a core element of the pattern being demonstrated.

Nella dimostrazione viene utilizzato di Visual c# iteratori (usando il yield``return costrutto parola chiave).The demonstration makes use of Visual C# iterators (using the yield``return keyword construct). Per ulteriori informazioni sugli iteratori, vedere l'argomento "Utilizzo degli iteratori" su MSDN.For more information about iterators, see the "Using Iterators" topic on MSDN.

ServiceService

Il servizio implementa un contratto WebGetAttribute di base che è costituito da un'operazione, come mostra il codice seguente.The service implements a basic WebGetAttribute contract that consists of one operation, as shown in the following code.

[ServiceContract]  
interface IStreamingFeedService  
{  
    [WebGet]  
    [OperationContract]  
    Atom10FeedFormatter StreamedFeed();  
}  

Il servizio implementa il contratto utilizzando una classe ItemGenerator per creare un flusso potenzialmente infinito di istanze SyndicationItem utilizzando un iteratore, come mostra il codice seguente.The service implements this contract by using an ItemGenerator class to create a potentially infinite stream of SyndicationItem instances using an iterator, as shown in the following code.

class ItemGenerator  
{  
    public IEnumerable<SyndicationItem> GenerateItems()  
    {  
        while (counter.GetCount() < maxItemsRead)  
        {  
            itemsReturned++;  
            yield return CreateNextItem();  
        }  

    }  
    ...  
}  

Quando l'implementazione del servizio crea il feed, viene utilizzato l'output di ItemGenerator.GenerateItems() invece di una raccolta di elementi memorizzato nel buffer.When the service implementation creates the feed, the output of ItemGenerator.GenerateItems() is used instead of a buffered collection of items.

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();  
}  

Di conseguenza, il flusso dell'elemento non viene mai memorizzato pienamente nel buffer.As a result, the item stream is never fully buffered into memory. È possibile osservare questo comportamento impostando un punto di interruzione per il yield``return istruzione all'interno del ItemGenerator.GenerateItems() metodo e notare che il punto di interruzione viene rilevato per la prima volta dopo che il servizio ha restituito il risultato del StreamedFeed() metodo.You can observe this behavior by setting a breakpoint on the yield``return statement inside of the ItemGenerator.GenerateItems() method and noting that this breakpoint is encountered for the first time after the service has returned the result of the StreamedFeed() method.

ClientClient

Il client in questo esempio utilizza un'implementazione personalizzata della classe SyndicationFeedFormatter che rimanda la materializzazione di elementi singoli nel feed invece di memorizzarli nel buffer.The client in this sample uses a custom SyndicationFeedFormatter implementation that delays the materialization of individual items in the feed instead of buffering them into memory. Di seguito viene illustrata l'istanza personalizzata di StreamedAtom10FeedFormatter:The custom StreamedAtom10FeedFormatter instance is used as follows.

XmlReader reader = XmlReader.Create("http://localhost:8000/Service/Feeds/StreamedFeed");  
StreamedAtom10FeedFormatter formatter = new StreamedAtom10FeedFormatter(counter);  

SyndicationFeed feed = formatter.ReadFrom(reader);  

Normalmente, una chiamata al metodo ReadFrom(XmlReader) non restituisce alcun risultato fino a che il contenuto intero del feed non sia stato letto dalla rete e memorizzato nel buffer.Normally, a call to ReadFrom(XmlReader) does not return until the entire contents of the feed have been read from the network and buffered into memory. Tuttavia, l'oggetto StreamedAtom10FeedFormatter ignora il metodo ReadItems(XmlReader, SyndicationFeed, Boolean) per restituire un iteratore invece di una raccolta memorizzata nel buffer, come mostra il codice seguente.However, the StreamedAtom10FeedFormatter object overrides ReadItems(XmlReader, SyndicationFeed, Boolean) to return an iterator instead of a buffered collection, as shown in the following code.

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();  
}  

Di conseguenza, ogni elemento non viene letto dalla rete fino a che l'applicazione client che attraversa i risultati di ReadItems() non è pronta a utilizzarli.As a result, each item is not read from the network until the client application traversing the results of ReadItems() is ready to use it. È possibile osservare questo comportamento impostando un punto di interruzione per il yield``return istruzione all'interno di StreamedAtom10FeedFormatter.DelayReadItems() e osservare che il punto di interruzione viene rilevato per la prima volta dopo la chiamata a ReadFrom() viene completata.You can observe this behavior by setting a breakpoint on the yield``return statement inside of StreamedAtom10FeedFormatter.DelayReadItems() and noticing that this breakpoint is encountered for the first time after the call to ReadFrom() completes.

Nelle istruzioni seguenti viene illustrato come compilare ed eseguire l'esempio.The following instructions show how to build and run the sample. Notare che anche se il server smette di generare elementi dopo che il client ha letto 10 elementi, l'output mostra che il client ne legge molti più di 10.Note that although the server stops generating items after the client has read 10 items, the output shows that the client reads significantly more than 10 items. Ciò avviene perché l'associazione di rete utilizzata dall'esempio trasmette dati in segmenti di quattro kilobyte (KB).This is because the networking binding used by the sample transmits data in four-kilobyte (KB) segments. Di conseguenza, il client riceve 4 KB di dati dell'elemento prima che abbia la possibilità di leggere il primo elemento.As such, the client receives 4KB of item data before it has the opportunity to read even one item. Si tratta di un comportamento normale (trasmettere dati HTTP in segmenti di dimensioni ragionevolmente grandi aumenta le prestazioni).This is normal behavior (sending streamed HTTP data in reasonably-sized segments increases performance).

Per impostare, compilare ed eseguire l'esempioTo set up, build, and run the sample

  1. Assicurarsi di avere eseguito la procedura di installazione singola per gli esempi di Windows Communication Foundation.Ensure that you have performed the One-Time Setup Procedure for the Windows Communication Foundation Samples.

  2. Per compilare l'edizione in C# o Visual Basic .NET della soluzione, seguire le istruzioni in Building the Windows Communication Foundation Samples.To build the C# or Visual Basic .NET edition of the solution, follow the instructions in Building the Windows Communication Foundation Samples.

  3. Per eseguire l'esempio in una configurazione singola o tra computer, seguire le istruzioni in esegue gli esempi di Windows Communication Foundation.To run the sample in a single- or cross-machine configuration, follow the instructions in Running the Windows Communication Foundation Samples.

Importante

È possibile che gli esempi siano già installati nel computer.The samples may already be installed on your computer. Verificare la directory seguente (impostazione predefinita) prima di continuare.Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

Se questa directory non esiste, andare al Windows Communication Foundation (WCF) e gli esempi di Windows Workflow Foundation (WF) per .NET Framework 4 per scaricare tutti i Windows Communication Foundation (WCF) e WFWF esempi.If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WFWF samples. Questo esempio si trova nella directory seguente.This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WCF\Extensibility\Syndication\StreamingFeeds

Vedere ancheSee Also

Feed di diagnostica autonomoStand-Alone Diagnostics Feed