ilk commit
This commit is contained in:
66
src/DownloadManager.Core/Queue/DownloadQueue.cs
Normal file
66
src/DownloadManager.Core/Queue/DownloadQueue.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
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<DownloadItem, int> _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<DownloadItem?> 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();
|
||||
|
||||
/// <summary>Çalışma zamanında limit değiştir (ayarlar panelinden)</summary>
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user