You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
3.8 KiB

8 months ago
  1. using System;
  2. using System.Diagnostics;
  3. using System.Threading;
  4. namespace Mirle.Component.MPLC
  5. {
  6. /// <summary>
  7. ///
  8. /// </summary>
  9. public class ThreadWorker : IDisposable
  10. {
  11. #region Constructure
  12. /// <summary>
  13. ///
  14. /// </summary>
  15. /// <param name="task"></param>
  16. public ThreadWorker(Action task) : this(task, 100, true) { }
  17. /// <summary>
  18. ///
  19. /// </summary>
  20. /// <param name="task"></param>
  21. /// <param name="interval"></param>
  22. public ThreadWorker(Action task, int interval) : this(task, interval, true) { }
  23. /// <summary>
  24. ///
  25. /// </summary>
  26. /// <param name="task"></param>
  27. /// <param name="interval"></param>
  28. /// <param name="startFlag"></param>
  29. public ThreadWorker(Action task, int interval, bool startFlag)
  30. {
  31. _task = task;
  32. _interval = interval;
  33. Thread thr = new Thread(new ThreadStart(WorkProcess))
  34. {
  35. IsBackground = true
  36. };
  37. thr.Start();
  38. IsRunning = startFlag;
  39. }
  40. #endregion
  41. #region Properties
  42. /// <summary>
  43. ///
  44. /// </summary>
  45. private int _interval = 1000;
  46. /// <summary>
  47. ///
  48. /// </summary>
  49. private bool _runFlag = true;
  50. /// <summary>
  51. ///
  52. /// </summary>
  53. private DateTime _nextCanRunTime = DateTime.Now;
  54. /// <summary>
  55. ///
  56. /// </summary>
  57. private readonly Action _task;
  58. /// <summary>
  59. ///
  60. /// </summary>
  61. public int Interval
  62. {
  63. get => _interval;
  64. set => _interval = value < 100 ? 100 : value;
  65. }
  66. /// <summary>
  67. ///
  68. /// </summary>
  69. public bool IsRunning { get; private set; } = false;
  70. #endregion
  71. #region Method
  72. /// <summary>
  73. ///
  74. /// </summary>
  75. public void Pause()
  76. {
  77. IsRunning = false;
  78. }
  79. /// <summary>
  80. ///
  81. /// </summary>
  82. public void Start()
  83. {
  84. IsRunning = true;
  85. }
  86. /// <summary>
  87. ///
  88. /// </summary>
  89. private void WorkProcess()
  90. {
  91. while (_runFlag)
  92. {
  93. if (IsRunning && DateTime.Now > _nextCanRunTime)
  94. {
  95. try
  96. {
  97. _nextCanRunTime = DateTime.Now.AddMilliseconds(_interval);
  98. _task?.Invoke();
  99. }
  100. catch (Exception ex)
  101. {
  102. Debug.WriteLine($"{ex}");
  103. }
  104. }
  105. else if (_nextCanRunTime > DateTime.Now.AddMilliseconds(_interval))
  106. {
  107. _nextCanRunTime = DateTime.Now;
  108. continue;
  109. }
  110. SpinWait.SpinUntil(() => false, 10);
  111. }
  112. }
  113. #region Dispose
  114. private bool _disposedValue;
  115. /// <summary>
  116. ///
  117. /// </summary>
  118. /// <param name="disposing"></param>
  119. private void Dispose(bool disposing)
  120. {
  121. if (!_disposedValue)
  122. {
  123. if (disposing)
  124. {
  125. }
  126. _runFlag = false;
  127. _disposedValue = true;
  128. }
  129. }
  130. /// <summary>
  131. ///
  132. /// </summary>
  133. ~ThreadWorker()
  134. {
  135. Dispose(false);
  136. }
  137. /// <summary>
  138. ///
  139. /// </summary>
  140. public void Dispose()
  141. {
  142. Dispose(true);
  143. GC.SuppressFinalize(this);
  144. }
  145. #endregion Dispose
  146. #endregion
  147. }
  148. }