using System; using System.Diagnostics; using System.Threading; namespace Mirle.Component.MPLC { /// /// /// public class ThreadWorker : IDisposable { #region Constructure /// /// /// /// public ThreadWorker(Action task) : this(task, 100, true) { } /// /// /// /// /// public ThreadWorker(Action task, int interval) : this(task, interval, true) { } /// /// /// /// /// /// public ThreadWorker(Action task, int interval, bool startFlag) { _task = task; _interval = interval; Thread thr = new Thread(new ThreadStart(WorkProcess)) { IsBackground = true }; thr.Start(); IsRunning = startFlag; } #endregion #region Properties /// /// /// private int _interval = 1000; /// /// /// private bool _runFlag = true; /// /// /// private DateTime _nextCanRunTime = DateTime.Now; /// /// /// private readonly Action _task; /// /// /// public int Interval { get => _interval; set => _interval = value < 100 ? 100 : value; } /// /// /// public bool IsRunning { get; private set; } = false; #endregion #region Method /// /// /// public void Pause() { IsRunning = false; } /// /// /// public void Start() { IsRunning = true; } /// /// /// private void WorkProcess() { while (_runFlag) { if (IsRunning && DateTime.Now > _nextCanRunTime) { try { _nextCanRunTime = DateTime.Now.AddMilliseconds(_interval); _task?.Invoke(); } catch (Exception ex) { Debug.WriteLine($"{ex}"); } } else if (_nextCanRunTime > DateTime.Now.AddMilliseconds(_interval)) { _nextCanRunTime = DateTime.Now; continue; } SpinWait.SpinUntil(() => false, 10); } } #region Dispose private bool _disposedValue; /// /// /// /// private void Dispose(bool disposing) { if (!_disposedValue) { if (disposing) { } _runFlag = false; _disposedValue = true; } } /// /// /// ~ThreadWorker() { Dispose(false); } /// /// /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } #endregion Dispose #endregion } }