.NET Channels Yüksek Performanslı Veri Akışı Yönetimi

18 Şubat 2025

Modern yazılım dünyasında, eşzamanlı (concurrent) işlemler ve veri akışı yönetimi, performans açısından büyük önem taşır. .NET Channels, .NET ekosisteminde etkin bir şekilde veri akışı sağlamak ve eşzamanlı işlemleri yönetmek için geliştirilmiş güçlü bir araçtır. System.Threading.Channels kütüphanesi ile gelen bu özellik, multi-threaded ve asynchronous sistemlerde veri iletişimini optimize etmek için idealdir.

Bu yazıda, .NET Channels nedir, nasıl çalışır ve hangi senaryolarda kullanılır? gibi sorulara cevap bulacağız.

 1) .NET Channels Nedir?

- .NET Channels, üretici-tüketici (producer-consumer) modelini temel alan, kanallar (channels) üzerinden veri paylaşımı sağlayan bir iletişim yapısıdır.
- Veri paylaşımını yönetirken, performansı artırmak ve iş parçacıkları (threads) arasında senkronizasyon sağlamak için optimize edilmiştir.
- Task-based asenkron programlama ile mükemmel uyumlu çalışır.

* Kullanım Alanları
- Gerçek zamanlı veri akışı (örneğin: mesaj kuyruğu, log sistemi)
- Yüksek performanslı çok iş parçacıklı uygulamalar
- Veri işleme hatlarını (pipeline) yönetme
- Asenkron iş parçacıkları arasında iletişim kurma


2) .NET Channels’ın Avantajları

- Thread-safe (İş Parçacığı Güvenliği): Çok iş parçacıklı ortamlarda veri paylaşımını güvenli bir şekilde sağlar.
- Backpressure Desteği: Kanal dolduğunda veya tüketici yavaş çalıştığında üreticiyi durdurabilir.
- FIFO (First In First Out) Yapısı: Verileri sıralı olarak işler ve veri kaybı yaşanmasını engeller.
- Asenkron Çalışma: async ve await desteğiyle, yüksek performanslı ve ölçeklenebilir kod yazmayı sağlar.
- Bloklamayan (Non-Blocking) Yapı: İş parçacıkları arasında veri aktarımı yaparken, kilitleme (lock) kullanmadan yüksek verimlilik sağlar.


3) .NET Channels Nasıl Kullanılır?

Temel Kullanım

.NET Channels kütüphanesi, System.Threading.Channels namespace’i altında bulunur.
Kanal oluşturmak için Channel.CreateUnbounded<T>() veya Channel.CreateBounded<T>() kullanılır.

CreateUnbounded<T>() - Sonsuz Kapasiteye Sahip Kanal

class Program
{
    static async Task Main()
    {
        // Sonsuz kapasiteye sahip bir kanal oluştur
        var channel = Channel.CreateUnbounded<int>();

        // Veri üreten üretici (Producer)
        _ = Task.Run(async () =>
        {
            for (int i = 1; i <= 5; i++)
            {
                await channel.Writer.WriteAsync(i);
                Console.WriteLine($"Üretildi: {i}");
                await Task.Delay(500);
            }
            channel.Writer.Complete(); // Yazma işlemi tamamlandı
        });

        // Veriyi işleyen tüketici (Consumer)
        await foreach (var item in channel.Reader.ReadAllAsync())
        {
            Console.WriteLine($"Tüketildi: {item}");
        }
    }
}

 

 

- Yukarıdaki kod, bir üretici (producer) tarafından yazılan verileri, bir tüketici (consumer) tarafından okuyan basit bir veri akışı modelidir.
- Üretici 5 adet veri üretir, tüketici ise bu verileri sırayla okur.
- channel.Writer.Complete() metodu, kanaldaki verilerin bittiğini belirtir.


 CreateBounded<T>() - Belirli Kapasiteye Sahip Kanal

Eğer belirli bir kapasite sınırı belirlenmek isteniyorsa, CreateBounded<T>() kullanılabilir.

var channel = Channel.CreateBounded<int>(new BoundedChannelOptions(3)
{
    FullMode = BoundedChannelFullMode.Wait // Kanal dolduğunda bekle
});

Bu yapı, kanal dolduğunda yeni veri eklenmesini bekleyerek, sistemin aşırı yüklenmesini engeller.


4) .NET Channels’ın Kullanım Senaryoları

1. Gerçek Zamanlı Log İşleme

Büyük ölçekli sistemlerde log verilerinin işlenmesi, Channels ile kolayca yönetilebilir.
Örneğin, log verileri bir kanalda biriktirilir ve arka planda bir tüketici bu verileri veritabanına veya bir dosyaya kaydeder.

public class Logger
{
    private readonly Channel<string> _logChannel = Channel.CreateUnbounded<string>();

    public Logger()
    {
        Task.Run(async () =>
        {
            await foreach (var log in _logChannel.Reader.ReadAllAsync())
            {
                Console.WriteLine($"Log kaydedildi: {log}");
            }
        });
    }

    public async Task LogMessage(string message)
    {
        await _logChannel.Writer.WriteAsync(message);
    }
}

 

Bu sayede log mesajları biriktirilir ve tüketici tarafından sırayla işlenir.


2. Gerçek Zamanlı Mesajlaşma Uygulaması

.NET Channels, gerçek zamanlı bir mesaj kuyruğu oluşturmak için kullanılabilir.
Örneğin, bir canlı sohbet (chat) uygulamasında, gelen mesajları işlemek için bir kanal kullanılabilir.

public class ChatService
{
    private readonly Channel<string> _messageChannel = Channel.CreateUnbounded<string>();

    public ChatService()
    {
        Task.Run(async () =>
        {
            await foreach (var message in _messageChannel.Reader.ReadAllAsync())
            {
                Console.WriteLine($"Yeni mesaj: {message}");
            }
        });
    }

    public async Task SendMessage(string message)
    {
        await _messageChannel.Writer.WriteAsync(message);
    }
}

 

Kullanıcılar SendMessage() metodunu çağırarak mesaj gönderir ve kanal aracılığıyla mesajlar işlenir.


5) .NET Channels ile Task.Run Kullanımı

Channels, Task.Run ile birlikte kullanılarak paralel iş parçacıkları (threads) arasında veri paylaşımını optimize eder.

 

var channel = Channel.CreateUnbounded<int>();

Task.Run(async () =>
{
    for (int i = 0; i < 10; i++)
    {
        await channel.Writer.WriteAsync(i);
    }
    channel.Writer.Complete();
});

await Task.Run(async () =>
{
    await foreach (var item in channel.Reader.ReadAllAsync())
    {
        Console.WriteLine($"Veri işlendi: {item}");
    }
});

 

Yorumlar
damla ceylan - 18.02.2025 16:27:27
eline sağlık. :)
Sitenizden gelir elde etmeye hazır mısınız?
Benim de kullandığım reklam platformu: Monetag
Monetag’e Göz At 🚀