BackgroundWorkerQueue.cs 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  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.Tasks;
  8. namespace TEAMModelOS.Function.DI
  9. {
  10. public class BackgroundWorkerQueue
  11. {
  12. private readonly ConcurrentQueue<Func<CancellationToken, Task>> _workItems = new();
  13. private readonly SemaphoreSlim _signal = new(0);
  14. public async Task<Func<CancellationToken, Task>> DequeueAsync(CancellationToken cancellationToken)
  15. {
  16. await _signal.WaitAsync(cancellationToken);
  17. _workItems.TryDequeue(out var workItem);
  18. return workItem;
  19. }
  20. public void QueueBackgroundWorkItem(Func<CancellationToken, Task> workItem)
  21. {
  22. ArgumentNullException.ThrowIfNull(workItem);
  23. _workItems.Enqueue(workItem);
  24. _signal.Release();
  25. }
  26. }
  27. public class LongRunningService : BackgroundService
  28. {
  29. public LongRunningService(BackgroundWorkerQueue queue)
  30. {
  31. _queue = queue;
  32. }
  33. private readonly BackgroundWorkerQueue _queue;
  34. protected override async Task ExecuteAsync(CancellationToken stoppingToken)
  35. {
  36. while (!stoppingToken.IsCancellationRequested)
  37. {
  38. var workItem = await _queue.DequeueAsync(stoppingToken);
  39. await workItem(stoppingToken);
  40. }
  41. }
  42. }
  43. }