title: Task queue without waiting for results
body: <p>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.</p>
  <pre><code>public interface IBackgroundTaskQueue
  {
      void QueueBackgroundWorkItem(Task? workItem, CancellationToken cancellationToken);
  
      Task&lt;Task?&gt; DequeueAsync(
          CancellationToken cancellationToken);
  }
  
  
  public class BackgroundTaskQueue : IBackgroundTaskQueue
  {
      private readonly ConcurrentQueue&lt;Task?&gt; _workItems = new();
      private readonly ILogger&lt;BackgroundTaskQueue&gt; _logger;
      private readonly SemaphoreSlim _signal = new(0);
  
      public BackgroundTaskQueue(ILogger&lt;BackgroundTaskQueue&gt; 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, &quot;An error has occurred whilst attempting to dequeue the background work que.&quot;);
          }
  
      }
  
      public async Task&lt;Task?&gt; DequeueAsync(CancellationToken cancellationToken)
      {
          try
          {
              await _signal.WaitAsync(cancellationToken);
              _workItems.TryDequeue(out var workItem);
  
              return workItem;
          }
          catch (Exception ex)
          {
              _logger.LogWarning(ex, &quot;An error has occurred whilst attempting to dequeue the background work que.&quot;);
          }
  
          return null;
      }
  }
  </code></pre>