using DownloadManager.Core.Models; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace DownloadManager.Core.Queue; public class DownloadQueue { private SemaphoreSlim _concurrencySemaphore; private readonly SemaphoreSlim _itemsAvailableSemaphore = new(0); private readonly PriorityQueue _inner = new(); private readonly object _lock = new(); public DownloadQueue(int maxConcurrent = 3) => _concurrencySemaphore = new SemaphoreSlim(maxConcurrent, maxConcurrent); public void Enqueue(DownloadItem item) { lock (_lock) { _inner.Enqueue(item, item.Priority); _itemsAvailableSemaphore.Release(); } } public async Task DequeueAsync(CancellationToken ct) { // Önce bir slotun boşalmasını bekle (concurrency limit) await _concurrencySemaphore.WaitAsync(ct); try { // Sonra kuyrukta bir öğe olmasını bekle await _itemsAvailableSemaphore.WaitAsync(ct); lock (_lock) { if (_inner.TryDequeue(out var item, out _)) return item; } } catch { _concurrencySemaphore.Release(); throw; } return null; } public void Release() => _concurrencySemaphore.Release(); /// Çalışma zamanında limit değiştir (ayarlar panelinden) public void SetConcurrencyLimit(int newLimit) { lock (_lock) { // Not: Bu basit uygulama çalışma anındaki limit değişimini tam olarak yansıtmayabilir, // ama temel yapı için yeterli. var old = _concurrencySemaphore; _concurrencySemaphore = new SemaphoreSlim(newLimit, newLimit); old.Dispose(); } } }