Akış Beslemeleri Örneği

StreamingFeeds örneği, çok sayıda öğe içeren dağıtım akışlarının nasıl yönetileceğini gösterir. Sunucuda, örnek, her bir SyndicationItem nesnesinin oluşturulmasının, öğenin ağ akışına yazılmasından hemen önceye kadar nasıl ertelenebileceğini göstermektedir.

İstemcide örnek, özel bir besleme biçimlendiricisinin ağ akışından tek tek öğeleri okumak için nasıl kullanılabileceğini gösterir, böylece okunan besleme hiçbir zaman belleğe tamamen yüklenmez.

Dağıtım API'sinin akış özelliğini en iyi şekilde göstermek için bu örnek, sunucunun sonsuz sayıda öğe içeren bir akışı kullanıma sunma olasılığı düşük bir senaryo kullanır. Bu durumda sunucu, istemcinin akıştan belirtilen sayıda öğe okuduğunu belirleyene kadar akışta yeni öğeler oluşturmaya devam eder (varsayılan olarak 10). Kolaylık olması için hem istemci hem de sunucu aynı işlemde uygulanır ve istemcinin kaç öğe ürettiğini izlemek için paylaşılan ItemCounter bir nesne kullanır. Türü ItemCounter yalnızca örnek senaryonun temiz bir şekilde sonlandırılmasını sağlamak amacıyla mevcuttur ve gösterilen desenin temel öğesi değildir.

Gösterim, Visual C# yineleyicilerini (anahtar sözcük yapısını kullanarak yield return ) kullanır. Yineleyiciler hakkında daha fazla bilgi için MSDN'de "Yineleyicileri Kullanma" konusuna bakın.

Hizmet

Hizmet, aşağıdaki kodda gösterildiği gibi tek bir işlemden oluşan temel WebGetAttribute bir sözleşme uygular.

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

Hizmet, aşağıdaki kodda gösterildiği gibi bir ItemGenerator yineleyici kullanarak sonsuz olabilecek bir örnek akışı SyndicationItem oluşturmak için bir sınıf kullanarak bu sözleşmeyi uygular.

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

    }
    ...
}

Hizmet uygulaması beslemeyi oluşturduğunda, arabelleğe alınmış öğe koleksiyonu yerine ItemGenerator.GenerateItems()'nün çıktısı kullanılır.

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

Sonuç olarak, öğe akışı hiçbir zaman belleğe tam olarak arabelleklenmez. Yönteminin içindeki yield return deyiminde ItemGenerator.GenerateItems() bir kesme noktası ayarlayarak ve hizmet yöntemin sonucunu StreamedFeed() döndürdükten sonra bu kesme noktasıyla ilk kez karşılaşıldığını belirterek bu davranışı gözlemleyebilirsiniz.

Müşteri

Bu örnekteki istemci, akıştaki tek tek öğeleri belleğe arabelleğe almak yerine, bunların somutlaştırılmasını geciktiren özel bir SyndicationFeedFormatter uygulama kullanır. Özel StreamedAtom10FeedFormatter örnek aşağıdaki gibi kullanılır.

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

SyndicationFeed feed = formatter.ReadFrom(reader);

Normalde, ReadFrom(XmlReader) çağrısı, akışın tüm içeriği ağdan okunup belleğe arabelleğe alınana kadar geri dönmez. Ancak StreamedAtom10FeedFormatter nesnesi, aşağıdaki kodda gösterildiği gibi arabelleğe alınmış bir koleksiyon yerine bir yineleyici döndürmek için ReadItems(XmlReader, SyndicationFeed, Boolean)'i geçersiz kılar.

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

Sonuç olarak, sonuçları arasında geçiş yapılan ReadItems() istemci uygulaması kullanıma hazır olana kadar her öğe ağdan okunmuyor. yield return içindeki StreamedAtom10FeedFormatter.DelayReadItems() ifadesine bir kesme noktası ayarlayarak ve ReadFrom() çağrısı tamamlandıktan sonra bu kesme noktasına ilk kez ulaşılacağını fark ederek bu davranışı gözlemleyebilirsiniz.

Aşağıdaki yönergelerde, örneğin nasıl derlenip çalıştırılacağı gösterilmektedir. İstemci 10 öğeyi okuduktan sonra sunucu öğeleri oluşturmayı durdursa da, çıktının istemcinin 10'dan fazla öğeyi önemli ölçüde okuduğunu gösterdiğini unutmayın. Bunun nedeni, örnek tarafından kullanılan ağ bağlamasının verileri dört kilobaytlık (KB) kesimlerde iletmesidir. Bu nedenle, istemci bir öğeyi bile okuma fırsatına sahip olmadan önce 4 KB öğe verisi alır. Bu normal bir davranıştır (akışlı HTTP verilerini makul boyuttaki segmentlerde göndermek performansı artırır).

Örneği ayarlamak, derlemek ve çalıştırmak için

  1. Windows Communication Foundation Örnekleri içinOne-Time Kurulum Yordamını yaptığınızdan emin olun.

  2. Çözümün C# veya Visual Basic .NET sürümünü oluşturmak için Windows Communication Foundation Örneklerioluşturma başlığındaki yönergeleri izleyin.

  3. Örneği tek bir makine veya makineler arası bir yapılandırmada çalıştırmak için, Windows Communication Foundation örneklerini çalıştırmayönergelerini izleyin.

Ayrıca bakınız