AsyncWorkQueue.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Threading;
  4. namespace Ryujinx.Common
  5. {
  6. public sealed class AsyncWorkQueue<T> : IDisposable
  7. {
  8. private readonly Thread _workerThread;
  9. private readonly CancellationTokenSource _cts;
  10. private readonly Action<T> _workerAction;
  11. private readonly BlockingCollection<T> _queue;
  12. public bool IsCancellationRequested => _cts.IsCancellationRequested;
  13. public AsyncWorkQueue(Action<T> callback, string name = null) : this(callback, name, new BlockingCollection<T>())
  14. {
  15. }
  16. public AsyncWorkQueue(Action<T> callback, string name, BlockingCollection<T> collection)
  17. {
  18. _cts = new CancellationTokenSource();
  19. _queue = collection;
  20. _workerAction = callback;
  21. _workerThread = new Thread(DoWork) { Name = name };
  22. _workerThread.IsBackground = true;
  23. _workerThread.Start();
  24. }
  25. private void DoWork()
  26. {
  27. try
  28. {
  29. foreach (var item in _queue.GetConsumingEnumerable(_cts.Token))
  30. {
  31. _workerAction(item);
  32. }
  33. }
  34. catch (OperationCanceledException)
  35. {
  36. }
  37. }
  38. public void Cancel()
  39. {
  40. _cts.Cancel();
  41. }
  42. public void CancelAfter(int millisecondsDelay)
  43. {
  44. _cts.CancelAfter(millisecondsDelay);
  45. }
  46. public void CancelAfter(TimeSpan delay)
  47. {
  48. _cts.CancelAfter(delay);
  49. }
  50. public void Add(T workItem)
  51. {
  52. _queue.Add(workItem);
  53. }
  54. public void Add(T workItem, CancellationToken cancellationToken)
  55. {
  56. _queue.Add(workItem, cancellationToken);
  57. }
  58. public bool TryAdd(T workItem)
  59. {
  60. return _queue.TryAdd(workItem);
  61. }
  62. public bool TryAdd(T workItem, int millisecondsDelay)
  63. {
  64. return _queue.TryAdd(workItem, millisecondsDelay);
  65. }
  66. public bool TryAdd(T workItem, int millisecondsDelay, CancellationToken cancellationToken)
  67. {
  68. return _queue.TryAdd(workItem, millisecondsDelay, cancellationToken);
  69. }
  70. public bool TryAdd(T workItem, TimeSpan timeout)
  71. {
  72. return _queue.TryAdd(workItem, timeout);
  73. }
  74. public void Dispose()
  75. {
  76. _queue.CompleteAdding();
  77. _cts.Cancel();
  78. _workerThread.Join();
  79. _queue.Dispose();
  80. _cts.Dispose();
  81. }
  82. }
  83. }