I am wondering if anyone can help me I am trying to write a class which will create a task queue of tasks which runs without waiting for the result. I have a couple issues the first is I want to remove the completed tasks from the queue so that the task queue does not grow to large and when application shuts down it will clear/finish the task queue first.
public interface IBackgroundTaskQueue
{
void QueueBackgroundWorkItem(Task? workItem, CancellationToken cancellationToken);
Task<Task?> DequeueAsync(
CancellationToken cancellationToken);
}
public class BackgroundTaskQueue : IBackgroundTaskQueue
{
private readonly ConcurrentQueue<Task?> _workItems = new();
private readonly ILogger<BackgroundTaskQueue> _logger;
private readonly SemaphoreSlim _signal = new(0);
public BackgroundTaskQueue(ILogger<BackgroundTaskQueue> logger, IHostApplicationLifetime lifetime)
{
_logger = logger;
lifetime.ApplicationStopped.Register(OnStopping);
lifetime.ApplicationStopping.Register(OnStopping);
}
public void QueueBackgroundWorkItem(Task? workItem, CancellationToken cancellationToken)
{
if (workItem is null or { IsCanceled: true })
return;
_workItems.Enqueue(workItem);
_signal.Release();
}
private void OnStopping()
{
try
{
DequeueAsync(CancellationToken.None).GetAwaiter().GetResult();
}
catch (Exception ex)
{
_logger.LogWarning(ex, "An error has occurred whilst attempting to dequeue the background work que.");
}
}
public async Task<Task?> DequeueAsync(CancellationToken cancellationToken)
{
try
{
await _signal.WaitAsync(cancellationToken);
_workItems.TryDequeue(out var workItem);
return workItem;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "An error has occurred whilst attempting to dequeue the background work que.");
}
return null;
}
}