BackgroundWorkerQueue.cs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. using Microsoft.Extensions.Hosting;
  2. using System;
  3. using System.Collections.Concurrent;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading;
  8. using System.Threading.Tasks;
  9. namespace TEAMModelOS.SDK.DI
  10. {
  11. public class BackgroundWorkerQueue
  12. {
  13. private readonly ConcurrentQueue<Func<CancellationToken, Task>> _workItems = new();
  14. private readonly SemaphoreSlim _signal = new(0);
  15. public async Task<Func<CancellationToken, Task>> DequeueAsync(CancellationToken cancellationToken)
  16. {
  17. await _signal.WaitAsync(cancellationToken);
  18. _workItems.TryDequeue(out var workItem);
  19. return workItem;
  20. }
  21. public void QueueBackgroundWorkItem(Func<CancellationToken, Task> workItem)
  22. {
  23. ArgumentNullException.ThrowIfNull(workItem);
  24. _workItems.Enqueue(workItem);
  25. _signal.Release();
  26. }
  27. }
  28. public class LongRunningService : BackgroundService
  29. {
  30. public LongRunningService(BackgroundWorkerQueue queue)
  31. {
  32. _queue = queue;
  33. }
  34. private readonly BackgroundWorkerQueue _queue;
  35. protected override async Task ExecuteAsync(CancellationToken stoppingToken)
  36. {
  37. while (!stoppingToken.IsCancellationRequested)
  38. {
  39. var workItem = await _queue.DequeueAsync(stoppingToken);
  40. await workItem(stoppingToken);
  41. }
  42. }
  43. }
  44. }