System.Threading.Channels
Geri basınç denetimi için Channel, ChannelWriter ve ChannelReader kullanarak üretici-tüketici işlem hatları oluşturun.
System.Threading.Channels, CoddyKit'te ücretsiz bir C# Academy dersidir. Bu, 4 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 4 dersten oluşur.
Kanallar Nedir?
System.Threading.Channels (.NET Core 3 ile tanıtılmıştır), yüksek performanslı ve iş parçacığı güvenli bir üretici-tüketici kuyruğu sağlar. BlockingCollection'ın aksine kanallar tamamen asenkron ve ayırma açısından verimlidir — işlem hatları için idealdir.
Kanal Oluşturma
Kanallar bir fabrika ile oluşturulur. unbounded (sınırsız) veya bounded (geri basınç uygulayan sınırlı kapasiteye sahip) seçeneğini belirleyin. Fabrika, Writer ve Reader içeren bir Channel<T> döndürür.
using System.Threading.Channels;
// Unbounded: unlimited capacity, no backpressure
var unbounded = Channel.CreateUnbounded<string>();
// Bounded: max 100 items; writer waits when full
var bounded = Channel.CreateBounded<string>(100);
// Bounded with drop-oldest strategy:
var dropping = Channel.CreateBounded<string>(new BoundedChannelOptions(50)
{
FullMode = BoundedChannelFullMode.DropOldest
});Kanala Yazma
Üreticiler WriteAsync (bounded kanal doluysa bekler) veya TryWrite (kanal doluysa hemen false döndürür) kullanarak öğe yazar. Tamamlandığını Writer.Complete() ile bildirin.
var channel = Channel.CreateUnbounded<int>();
// Producer task
var producer = Task.Run(async () =>
{
for (int i = 0; i < 100; i++)
{
await channel.Writer.WriteAsync(i);
await Task.Delay(10);
}
channel.Writer.Complete(); // signal no more items
});Kanaldan Okuma
Tüketiciler ReadAllAsync() (en basit yaklaşım) ya da daha fazla denetim için ReadAsync/TryRead ile okur. ReadAllAsync, yazar Complete() çağırdığında tamamlanır.
// Consumer task
var consumer = Task.Run(async () =>
{
await foreach (var item in channel.Reader.ReadAllAsync())
{
Console.WriteLine($"Processed: {item}");
// Naturally paced — waits for next item
}
Console.WriteLine("Channel completed");
});
await Task.WhenAll(producer, consumer);Birden Çok Üretici
Kanallar iş parçacığı açısından güvenlidir. Birden çok üretici eş zamanlı olarak yazabilir — kilitleme gerekmez. Writer.Complete() çağrısını yalnızca tüm üreticiler işini bitirdikten sonra yapın.
var channel = Channel.CreateUnbounded<WorkItem>();
var producers = Enumerable.Range(0, 4).Select(id =>
Task.Run(async () =>
{
for (int i = 0; i < 25; i++)
await channel.Writer.WriteAsync(new WorkItem(id, i));
}));
// Wait for all producers before completing the writer
await Task.WhenAll(producers);
channel.Writer.Complete();Birden Çok Tüketici (Çoklu Dağıtım)
İşlemeyi paralelleştirmek için aynı kanal okuyucusu üzerinde birden çok tüketici görevi çalıştırın. Her öğe tam olarak bir tüketiciye iletilir (yayınlanmaz, bölüştürülür).
var channel = Channel.CreateBounded<WorkItem>(100);
// 4 parallel consumers
var consumers = Enumerable.Range(0, 4).Select(id =>
Task.Run(async () =>
{
await foreach (var item in channel.Reader.ReadAllAsync())
{
await ProcessItemAsync(item);
Console.WriteLine($"Consumer {id} processed {item.Id}");
}
}));
await Task.WhenAll(consumers);İşlem Hattı Deseni
Kanalları bir işlem hattında birbirine bağlayın: her aşama bir kanaldan okur, öğeleri işler ve sonraki kanala yazar. Aşamalar, doğal geri basınçla eş zamanlı çalışır.
// Stage 1: raw data
var stage1 = Channel.CreateBounded<string>(50);
// Stage 2: parsed
var stage2 = Channel.CreateBounded<ParsedRecord>(50);
// Stage 3: enriched
var stage3 = Channel.CreateBounded<EnrichedRecord>(50);
var parse = ParseStageAsync(stage1.Reader, stage2.Writer);
var enrich = EnrichStageAsync(stage2.Reader, stage3.Writer);
var persist = PersistStageAsync(stage3.Reader);
await Task.WhenAll(parse, enrich, persist);Sınırlı Kanallarla Geri Basınç
Sınırlı kapasiteli bir (bounded) kanal geri basıncı otomatik olarak uygular: kanal dolduğunda WriteAsync, tüketici öğeleri kanaldan alana kadar üreticiyi askıya alır. Elle yazılmış hız sınırlama koduna gerek yoktur.
// Bounded channel: max 10 items
var channel = Channel.CreateBounded<string>(10);
// Fast producer
var producer = Task.Run(async () =>
{
for (int i = 0; i < 1000; i++)
{
// WriteAsync waits when channel has 10 items
await channel.Writer.WriteAsync($"item-{i}");
// Producer is naturally slowed to consumer speed
}
channel.Writer.Complete();
});
// Slow consumer
var consumer = Task.Run(async () =>
{
await foreach (var item in channel.Reader.ReadAllAsync())
{
await Task.Delay(50); // simulate slow processing
Console.WriteLine(item);
}
});Kanallarda Hata İşleme
Hataları bekleyen tüm okuyuculara iletmek için Writer.Complete(exception) çağrısına bir özel durum aktarın. Okuyucular, kanal bir sonraki kez okunduğunda özel durumu görür.
var channel = Channel.CreateUnbounded<int>();
var producer = Task.Run(async () =>
{
try
{
for (int i = 0; i < 100; i++)
{
if (i == 50) throw new Exception("Producer failed at 50");
await channel.Writer.WriteAsync(i);
}
channel.Writer.Complete();
}
catch (Exception ex)
{
channel.Writer.Complete(ex); // propagate to reader
}
});
try
{
await foreach (var item in channel.Reader.ReadAllAsync())
Console.WriteLine(item);
}
catch (Exception ex)
{
Console.Error.WriteLine($"Channel error: {ex.Message}");
}Gerçek Dünya: Arka Plan İş Kuyruğu
Barındırılan bir hizmet ve kanal kullanan arka plan iş kuyruğu: HTTP istekleri işleri kuyruğa ekler; arka plan çalışanı bunları birer birer işler.
public class JobQueue
{
private readonly Channel<Func<CancellationToken, Task>> _queue
= Channel.CreateBounded<Func<CancellationToken, Task>>(100);
public ChannelWriter<Func<CancellationToken, Task>> Writer => _queue.Writer;
public ChannelReader<Func<CancellationToken, Task>> Reader => _queue.Reader;
}
public class JobProcessor : BackgroundService
{
private readonly JobQueue _queue;
public JobProcessor(JobQueue q) => _queue = q;
protected override async Task ExecuteAsync(CancellationToken ct)
{
await foreach (var job in _queue.Reader.ReadAllAsync(ct))
await job(ct);
}
}Hızlı Kontrol
Üretici, dolu bir sınırlı kapasiteli kanalda WriteAsync çağırdığında ne olur?
Özet: System.Threading.Channels
Önemli çıkarımlar:
- Kanallar, yüksek performanslı ve asenkron yapıya özgü üretici-tüketici kuyrukları sağlar
- unbounded: sınır yok; bounded: geri basınç veya düşürme stratejileriyle sınırlı kapasite
- Birden çok üretici ve tüketici, kilitleme olmadan güvenle çalışabilir
- ReadAllAsync() + await foreach = en temiz tüketim deseni
- Aşama tabanlı eş zamanlı işleme için kanalları işlem hatlarına bağlayın
- Akışın sonunu bildirmek için Writer.Complete() (veya Complete(exception)) çağrısını yapın
Sıkça Sorulan Sorular
“System.Threading.Channels” dersi ücretsiz mi?
Evet — “System.Threading.Channels” 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 4 dersten oluşur.
“System.Threading.Channels” dersinde ne öğreneceğim?
Geri basınç denetimi için Channel, ChannelWriter ve ChannelReader kullanarak üretici-tüketici işlem hatları oluşturun. 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, 4 dersinin 2. dersidir.
“System.Threading.Channels” 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
- IAsyncEnumerable ve await foreach
- System.Threading.Channels
- ValueTask ve Ayırmalardan Kaçınma
- ConfigureAwait ve Eşitleme Bağlamı