C# Academy · Ders

Kanallarla üretici/tüketici (genel bakış)

BlockingCollection kullanarak Channels benzeri üretici/tüketici kuyruklarını modelleyin: sınırlı arabellekler (geri basınç), birden çok tüketici ve düzgün tamamlanma.

2. ders / 38 adım

Kanallarla üretici/tüketici (genel bakış), CoddyKit'te ücretsiz bir C# Academy dersidir. Bu, 3 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C# Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C# Academy kursu toplamda 3 dersten oluşur.

Kavramlar ve hedefler

Hedef: Güvenli bir üretici/tüketici işlem hattı oluşturun.

  • Kanal fikri: üreticiler ile tüketiciler arasında bir queue
  • Sınırlı kapasite geri basınç sağlar
  • Birden çok tüketiciyi destekleyin
  • Temiz kapanma için CompleteAdding kullanın

Tek üretici/tüketici

Temel akış: üreticiler Add ile ekler, tüketiciler GetConsumingEnumerable üzerinde yineler, ardından bitirmek için CompleteAdding çağrılır.

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
  public static void Main(string[] args)
  {
    // Unbounded by default; simple demo
    BlockingCollection<int> queue = new BlockingCollection<int>();

    // Producer
    Task producer = Task.Run(() =>
    {
      for (int i = 1; i <= 5; i++)
      {
        queue.Add(i);                 // enqueue
        Console.WriteLine("Produced " + i);
        Thread.Sleep(50);             // simulate work
      }
      queue.CompleteAdding();         // signal no more items
    });

    // Consumer
    Task consumer = Task.Run(() =>
    {
      foreach (int x in queue.GetConsumingEnumerable())
      {
        Console.WriteLine("Consumed " + x);
        Thread.Sleep(80);             // simulate processing
      }
      Console.WriteLine("Consumer done");
    });

    Task.WaitAll(producer, consumer);
  }
}

Geri basınç gösterimi

Sınırlı kuyruklar geri basınç uygular: kuyruk dolduğunda, tüketiciler yer açana kadar Add engellenir.

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
  public static void Main(string[] args)
  {
    // Bounded capacity introduces backpressure
    BlockingCollection<int> queue = new BlockingCollection<int>(boundedCapacity: 2);

    Task producer = Task.Run(() =>
    {
      for (int i = 1; i <= 5; i++)
      {
        queue.Add(i); // blocks when the buffer is full
        Console.WriteLine("Produced " + i + " (count=" + queue.Count + ")");
      }
      queue.CompleteAdding();
    });

    Task consumer = Task.Run(() =>
    {
      foreach (int x in queue.GetConsumingEnumerable())
      {
        Console.WriteLine("Consumed " + x);
        Thread.Sleep(120); // slower consumer -> producer will block sometimes
      }
    });

    Task.WaitAll(producer, consumer);
  }
}

Tüketicilere yayılım

Birden çok tüketici öğeler için yarışır (yayılım). İş, iş parçacıkları arasında otomatik olarak paylaşılır.

using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
  public static void Main(string[] args)
  {
    BlockingCollection<int> queue = new BlockingCollection<int>(3);

    Task prod = Task.Run(() =>
    {
      for (int i = 1; i <= 8; i++)
      {
        queue.Add(i);
        Console.WriteLine("Produced " + i);
        Thread.Sleep(30);
      }
      queue.CompleteAdding();
    });

    // Start 2 consumers that compete for items
    Task[] consumers = Enumerable.Range(1, 2).Select(id => Task.Run(() =>
    {
      foreach (int x in queue.GetConsumingEnumerable())
      {
        Console.WriteLine("C" + id + " got " + x);
        Thread.Sleep(100);
      }
      Console.WriteLine("C" + id + " done");
    })).ToArray();

    Task.WaitAll(consumers.Concat(new[] { prod }).ToArray());
  }
}

Temiz tamamlanma

Kuyruk boşaldığında temiz biçimde tamamlamak için CompleteAdding ve GetConsumingEnumerable kullanın.

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
  static void Producer(BlockingCollection<string> q)
  {
    string[] lines = { "A", "B", "C", "D" };
    foreach (var s in lines)
    {
      q.Add(s);
      Console.WriteLine("Produced " + s);
    }
    q.CompleteAdding(); // signal completion
  }

  static void Consumer(BlockingCollection<string> q)
  {
    try
    {
      foreach (var item in q.GetConsumingEnumerable())
      {
        Console.WriteLine("Consumed " + item);
        Thread.Sleep(60);
      }
      Console.WriteLine("Consumer finished all items");
    }
    catch (InvalidOperationException)
    {
      // Thrown if taken after completion and empty; avoided by foreach above.
    }
  }

  public static void Main(string[] args)
  {
    var queue = new BlockingCollection<string>(2);
    Task p = Task.Run(() => Producer(queue));
    Task c = Task.Run(() => Consumer(queue));
    Task.WaitAll(p, c);
  }
}

İpuçları ve tuzaklar

İpuçları:

  • Bellek büyümesini önlemek için sınırlı arabellekleri tercih edin.
  • Tamamlanma sırasında oluşabilecek yarışları önlemek için GetConsumingEnumerable kullanın.
  • İş öğelerini küçük ve bağımsız tutun; paylaşılan durumdan kaçının.
  • İşin sessizce durmasını önlemek için hataları tüketicilerin içinde günlüğe kaydedin ve ele alın.

CompleteAdding amacı

Hızlı kontrol: Bir BlockingCollection üzerinde CompleteAdding() çağırmak ne yapar?

Özet

Özet: Kanalları taklit etmek için sınırlı bir BlockingCollection kullanın, işi birden çok tüketiciye yayın ve kontrollü kapanma için CompleteAdding kullanın.

Başlamak ücretsiz

Yapay zeka eğitmeniyle C# öğren — ücretsiz

Tarayıcında gerçek kod yaz ve çalıştır, 7/24 yapay zeka eğitmeninden anında yardım al; web'de ya da uygulamada kaldığın yerden devam et.

Kurslar
93
Dersler
346

Sıkça Sorulan Sorular

“Kanallarla üretici/tüketici (genel bakış)” dersi ücretsiz mi?

Evet — “Kanallarla üretici/tüketici (genel bakış)” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C# Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C# Academy kursu toplamda 3 dersten oluşur.

“Kanallarla üretici/tüketici (genel bakış)” dersinde ne öğreneceğim?

BlockingCollection kullanarak Channels benzeri üretici/tüketici kuyruklarını modelleyin: sınırlı arabellekler (geri basınç), birden çok tüketici ve düzgün tamamlanma. C# Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

C# Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te C# Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 3 dersinin 2. dersidir.

“Kanallarla üretici/tüketici (genel bakış)” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu C# Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her C# Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Parallel.ForEach ve PLINQ
  2. Kanallarla üretici/tüketici (genel bakış)
  3. İş hacmi ve gecikme ödünleşimleri
← C# Academy Sayfasına Dön