ASP.NET Core SemaphoreSlim Nedir? ConcurrentDictionary Nedir?

post-thumb

1. SemaphoreSlim Nedir, Ne İşe Yarar, Ne Durumlarda Kullanılmalıdır?

SemaphoreSlim .NET'te kullanılan hafif bir semaphore (semafor) sınıfıdır. Bir semaphore, aynı anda yalnızca belirli sayıda iş parçacığının (thread) belirli bir kaynağa erişmesine izin vermek için kullanılan bir senkronizasyon aracıdır.

  • Ne İşe Yarar? SemaphoreSlim, belirli bir kaynak havuzuna erişimi sınırlamak için kullanılır. Örneğin, bir uygulamada aynı anda yalnızca belirli sayıda iş parçacığının belirli bir işlevi veya kaynağı kullanmasını istiyorsanız, SemaphoreSlim kullanılabilir. Bu sayede, birden fazla iş parçacığı aynı kaynağa erişmeye çalıştığında, yalnızca belirli bir sayıdaki iş parçacığı geçiş yapabilir, geri kalan iş parçacıkları ise bir kuyruğa alınır ve sıralarını bekler.

  • Ne Durumlarda Kullanılmalıdır? SemaphoreSlim, özellikle aşağıdaki durumlarda kullanılabilir:

    • Aynı anda sınırlı sayıda iş parçacığının belirli bir işlemi gerçekleştirmesine izin verilmesi gerektiğinde.
    • Ağ bağlantıları, dosya erişimleri gibi sınırlı kaynaklar üzerinde erişim denetimi gerektiğinde.
    • Paralel programlamada, birden fazla iş parçacığının aynı kaynağa erişimini kontrol altına almak için.
  • Thread Safety ve SemaphoreSlim: .NET'teki birçok veri yapısı ve sınıf, thread-safe olarak tasarlanmıştır. Ancak, bazı durumlarda uygulamanızda belirli bir kaynağa erişimi sınırlandırmanız gerekebilir. Örneğin, aynı anda yalnızca belirli sayıda veritabanı bağlantısına izin vermek isteyebilirsiniz. Bu tür durumlarda, SemaphoreSlim gibi senkronizasyon araçları kullanılabilir. Bu nedenle, SemaphoreSlim gibi bir aracın kullanımı, uygulamanızın ihtiyaçlarına bağlıdır.

Bu bağlamda SemaphoreSlim kullanımına dair bir örneğe göz atalım. 

using Microsoft.AspNetCore.Mvc;
using System.Threading;
using System.Threading.Tasks;

namespace YourNamespace.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class SemaphoreExampleController : ControllerBase
    {
        // SemaphoreSlim nesnesi oluşturuluyor. 1 değeri, aynı anda sadece bir thread'in erişimine izin verir.
        private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);

        [HttpGet("process")]
        public async Task<IActionResult> Process()
        {
            // Semaphore'un alınması. Burada diğer thread'lerin girişi engellenir.
            await _semaphore.WaitAsync();

            try
            {
                // Kritik bölüm: Burada sadece bir thread çalışabilir.
                // Örneğin, veri tabanına kayıt yapma gibi işlem yapılabilir.
                await Task.Delay(2000); // Simülasyon amaçlı gecikme

                return Ok("İşlem başarıyla tamamlandı.");
            }
            finally
            {
                // Semaphore serbest bırakılıyor, böylece başka bir thread girebilir.
                _semaphore.Release();
            }
        }
    }
}
  • SemaphoreSlim: SemaphoreSlim, belirli bir kaynağa aynı anda kaç thread'in erişebileceğini kontrol eden bir senkronizasyon nesnesidir. Yukarıdaki örnekte, SemaphoreSlim(1, 1) ile oluşturulmuştur, bu da aynı anda yalnızca bir thread'in Process metoduna erişmesine izin verir.
  • Semaphore'u Kullanma (WaitAsync): await _semaphore.WaitAsync(); satırı, semaphore'u almaya çalışır. Eğer başka bir thread o anda semaphore'u aldıysa, bu satır o thread'in semaphore'u serbest bırakmasını bekler.
  • Kritik Bölüm: Semaphore'u aldıktan sonra, try bloğu içindeki kod çalıştırılır. Bu bölümde, aynı anda yalnızca bir thread çalışabilir. Bu, örneğin bir veri tabanı güncellemesi veya dosya yazma gibi işlemler için kullanışlıdır.
  • Semaphore'u Serbest Bırakma (Release): finally bloğu içinde SemaphoreSlim.Release() metodu çağrılarak semaphore serbest bırakılır, böylece başka bir thread bu kaynağa erişebilir.

Kullanım Durumu:

SemaphoreSlim, aynı anda birden fazla işlem yapılmasını istemediğiniz durumlarda kullanışlıdır. Örneğin, bir dosya üzerinde aynı anda birden fazla yazma işlemi yapılmasını önlemek için veya bir veritabanına aynı anda birden fazla güncelleme yapılmasını engellemek için kullanılabilir.

Bu şekilde, SemaphoreSlim kritik bölgeye erişimi sınırlandırarak veri tutarlılığını ve thread güvenliğini sağlar. DotNet framework'ün kendi thread-safe mekanizmaları olsa da, SemaphoreSlim gibi yapılar, özellikle aynı anda birden fazla kaynağın erişimini kontrol etmek istediğinizde kullanışlıdır.

2. ConcurrentDictionary Nedir, Dictionary ile Farkı Nedir?

ConcurrentDictionary, .NET Framework'te kullanılan, thread-safe bir veri yapısıdır. Aynı anda birden fazla iş parçacığının güvenli bir şekilde veri eklemesine, çıkarmasına veya güncellemesine izin verir.

Dictionary ile Farkı Nedir?

  1. Thread Safety (İş Parçacığı Güvenliği):

    • Dictionary: Tek iş parçacıklı ortamlarda güvenli bir şekilde kullanılabilir, ancak birden fazla iş parçacığının aynı anda eriştiği durumlarda thread-safe değildir. Bu nedenle, Dictionary'yi birden fazla iş parçacığının aynı anda erişmesi gerektiğinde manuel olarak kilitlemeniz (lock) gerekir.
    • ConcurrentDictionary: Birden fazla iş parçacığının aynı anda veri eklemesine, çıkarmasına veya güncellemesine izin verir ve bu işlemleri thread-safe bir şekilde gerçekleştirir. Herhangi bir manuel kilitleme (lock) yapısına gerek yoktur.
  2. Performans:

    • Dictionary: Tek iş parçacıklı ortamlarda daha hızlıdır çünkü ek bir kilitleme maliyeti yoktur.
    • ConcurrentDictionary: İş parçacığı güvenliği sağlamak için ek işlem yükü vardır, bu da tek iş parçacıklı senaryolarda Dictionary'ye göre biraz daha yavaş olabileceği anlamına gelir. Ancak, çok iş parçacıklı senaryolarda kilitleme (lock) işlemlerini manuel olarak yönetmek yerine ConcurrentDictionary kullanmak genellikle daha verimlidir.
  3. Kullanım Senaryoları:

    • Dictionary: Uygulamanızda yalnızca bir iş parçacığı tarafından erişilecek veri yapıları için uygundur.
    • ConcurrentDictionary: Aynı veri yapısına birden fazla iş parçacığının eriştiği ve veri ekleyip çıkardığı çok iş parçacıklı uygulamalar için uygundur.

Özet:

  • SemaphoreSlim: Belirli bir kaynağa aynı anda kaç iş parçacığının erişebileceğini kontrol etmek için kullanılır. Her ne kadar .NET'te birçok sınıf thread-safe olarak sunulsa da, SemaphoreSlim gibi senkronizasyon araçları, belirli senaryolarda önemli bir rol oynar.
  • ConcurrentDictionary: Birden fazla iş parçacığının aynı anda veri ekleyip çıkardığı durumlar için thread-safe bir çözüm sunar ve Dictionary'ye göre bu tür senaryolarda daha güvenilirdir.