NextQueue.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Threading.Tasks;
  5. namespace PlatformBenchmarks
  6. {
  7. public class NextQueue : IDisposable
  8. {
  9. public NextQueue()
  10. {
  11. mQueue = new System.Collections.Concurrent.ConcurrentQueue<IEventWork>();
  12. }
  13. private readonly object _workSync = new object();
  14. private bool _doingWork;
  15. private int mCount;
  16. private System.Collections.Concurrent.ConcurrentQueue<IEventWork> mQueue;
  17. public int Count => System.Threading.Interlocked.Add(ref mCount, 0);
  18. public void Enqueue(IEventWork item)
  19. {
  20. mQueue.Enqueue(item);
  21. System.Threading.Interlocked.Increment(ref mCount);
  22. lock (_workSync)
  23. {
  24. if (!_doingWork)
  25. {
  26. System.Threading.ThreadPool.QueueUserWorkItem(OnStart);
  27. _doingWork = true;
  28. }
  29. }
  30. }
  31. private void OnError(Exception e, IEventWork work)
  32. {
  33. try
  34. {
  35. Error?.Invoke(e, work);
  36. }
  37. catch
  38. {
  39. }
  40. }
  41. public static Action<Exception, IEventWork> Error { get; set; }
  42. private async void OnStart(object state)
  43. {
  44. while (true)
  45. {
  46. while (mQueue.TryDequeue(out IEventWork item))
  47. {
  48. System.Threading.Interlocked.Decrement(ref mCount);
  49. using (item)
  50. {
  51. try
  52. {
  53. await item.Execute();
  54. }
  55. catch (Exception e_)
  56. {
  57. OnError(e_, item);
  58. }
  59. }
  60. }
  61. lock (_workSync)
  62. {
  63. if (mQueue.IsEmpty)
  64. {
  65. try
  66. {
  67. Unused?.Invoke();
  68. }
  69. catch { }
  70. _doingWork = false;
  71. return;
  72. }
  73. }
  74. }
  75. }
  76. public Action Unused { get; set; }
  77. public void Dispose()
  78. {
  79. while (mQueue.TryDequeue(out IEventWork work))
  80. {
  81. try
  82. {
  83. work.Dispose();
  84. }
  85. catch
  86. {
  87. }
  88. }
  89. }
  90. }
  91. }