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

using System;
using System.Diagnostics;
using System.Threading;
namespace Mirle.Component.MPLC
{
/// <summary>
///
/// </summary>
public class ThreadWorker : IDisposable
{
#region Constructure
/// <summary>
///
/// </summary>
/// <param name="task"></param>
public ThreadWorker(Action task) : this(task, 100, true) { }
/// <summary>
///
/// </summary>
/// <param name="task"></param>
/// <param name="interval"></param>
public ThreadWorker(Action task, int interval) : this(task, interval, true) { }
/// <summary>
///
/// </summary>
/// <param name="task"></param>
/// <param name="interval"></param>
/// <param name="startFlag"></param>
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
/// <summary>
///
/// </summary>
private int _interval = 1000;
/// <summary>
///
/// </summary>
private bool _runFlag = true;
/// <summary>
///
/// </summary>
private DateTime _nextCanRunTime = DateTime.Now;
/// <summary>
///
/// </summary>
private readonly Action _task;
/// <summary>
///
/// </summary>
public int Interval
{
get => _interval;
set => _interval = value < 100 ? 100 : value;
}
/// <summary>
///
/// </summary>
public bool IsRunning { get; private set; } = false;
#endregion
#region Method
/// <summary>
///
/// </summary>
public void Pause()
{
IsRunning = false;
}
/// <summary>
///
/// </summary>
public void Start()
{
IsRunning = true;
}
/// <summary>
///
/// </summary>
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;
/// <summary>
///
/// </summary>
/// <param name="disposing"></param>
private void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
}
_runFlag = false;
_disposedValue = true;
}
}
/// <summary>
///
/// </summary>
~ThreadWorker()
{
Dispose(false);
}
/// <summary>
///
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion Dispose
#endregion
}
}