LoopWorker.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using System;
  2. using System.Threading.Tasks;
  3. using Quadarax.Foundation.Core.Logging;
  4. namespace Quadarax.Foundation.Core.Thread
  5. {
  6. public class LoopWorker : AbstractWorker
  7. {
  8. #region *** Private fields ***
  9. private TimeSpan _defaultTimeout;
  10. private long _cntLimit;
  11. private Func<IWorkerContext?, Task>? _customIteration;
  12. private bool _isIterationRunning = false;
  13. #endregion
  14. #region *** Properties ***
  15. public long IterationsLimit { get; set; } = 0;
  16. public TimeSpan IterationsDelayBetween { get; set; } = TimeSpan.Zero;
  17. /// <summary>
  18. /// Defines if overlap iteration is allowed. If false, iteration is skipped if previous iteration is not finished.
  19. /// Default value is false.
  20. /// </summary>
  21. public bool AllowOverlap { get; set; } = false;
  22. #endregion
  23. #region *** Constructors ***
  24. public LoopWorker(IWorkerContext context) : base(context)
  25. {
  26. }
  27. public LoopWorker(string workerName, IWorkerContext? context) : base(workerName, context)
  28. {
  29. }
  30. public LoopWorker(string workerName) : base(workerName)
  31. {
  32. }
  33. public LoopWorker(string workerName, IWorkerContext? context, ILogger? logger = null) : base(workerName, context, logger)
  34. {
  35. }
  36. public LoopWorker(string workerName, IWorkerContext? context,Func<IWorkerContext?, Task>? customIteration = null, ILogger? logger = null) : base(workerName, context, logger)
  37. {
  38. _customIteration = customIteration;
  39. }
  40. #endregion
  41. #region *** Public Operations ***
  42. #endregion
  43. #region *** Virtuals and protected ***
  44. protected override async Task Do(IWorkerContext? context)
  45. {
  46. var exit = false;
  47. var first = true;
  48. while (!exit)
  49. {
  50. if (first)
  51. first = false;
  52. else if (IterationsDelayBetween != TimeSpan.Zero)
  53. await Task.Delay(IterationsDelayBetween);
  54. //System.Threading.Thread.CurrentThread.Join(IterationsDelayBetween);
  55. if (_isIterationRunning && !AllowOverlap)
  56. {
  57. await Task.Delay(100);
  58. continue;
  59. }
  60. _isIterationRunning = true;
  61. if (IterationsLimit == 0)
  62. {
  63. if (_customIteration != null)
  64. await _customIteration(context);
  65. else
  66. await DoIteration(context);
  67. }
  68. else
  69. {
  70. if (_customIteration != null)
  71. await _customIteration(context);
  72. else
  73. await DoIteration(context);
  74. _cntLimit++;
  75. if (_cntLimit > IterationsLimit)
  76. exit = true;
  77. }
  78. _isIterationRunning = false;
  79. }
  80. }
  81. #pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
  82. protected virtual async Task DoIteration(IWorkerContext? context)
  83. #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
  84. {
  85. }
  86. protected override void OnBeforeStart()
  87. {
  88. base.OnBeforeStart();
  89. _defaultTimeout = Timeout;
  90. Timeout = TimeSpan.Zero;
  91. }
  92. protected override void OnAfterStop()
  93. {
  94. base.OnAfterStop();
  95. Timeout = _defaultTimeout;
  96. _cntLimit = 0;
  97. }
  98. #endregion
  99. #region *** Private Operations ***
  100. #endregion
  101. }
  102. }