wcs_server_s7_baoying/Tools/CirculateTool/StartCirculation.cs

110 lines
3.6 KiB
C#
Raw Permalink Normal View History

2024-06-20 09:23:01 +08:00
using System.Reflection;
namespace CirculateTool;
/*
*
* 20230415
*
* 使
*
*/
/// <summary>
/// 定时任务类
/// </summary>
public class StartCirculation
{
/// <summary>
/// 触发的异常
/// </summary>
public event ExceptionHandlerEvent? ExceptionHandler;
public delegate void ExceptionHandlerEvent(string methodDescription, Exception ex);
/// <summary>
/// 显示相关信息
/// </summary>
public event MessageHandlerEvent? MessageHandler;
public delegate void MessageHandlerEvent(string message);
/// <summary>
/// 默认的循环时间
/// </summary>
private readonly int _defaultCirculationTime = 500;
/// <summary>
/// 启动一个程序集里面带有<see cref="CirculationAttribute"/>的类里面的定时方法
/// </summary>
/// <param name="assembly"></param>
/// <param name="instanceParams"></param>
public virtual void StartAssemblyCirculation(Assembly assembly, object[]? instanceParams = null)
{
Type[] types = assembly.GetTypes();
if (types.Length == 0) return;
foreach (Type type in types)
{
var attributes = type.GetCustomAttributes(false);
foreach (var attribute in attributes)
{
if (attribute is not CirculationAttribute) continue;
StartTask(type, instanceParams);
break;
}
}
}
/// <summary>
/// 开启一个实例里面所有已经添加了特性<see cref="CirculationAttribute"/>的方法
/// </summary>
/// <param name="type"></param>
/// <param name="instanceParams"></param>
public virtual void StartTask(Type type, object[]? instanceParams = null)
{
var methods = type.GetMethods();
foreach (var method in methods)
{
var attributes = method.GetCustomAttributes(false);
foreach (var attribute in attributes)
{
if (attribute is not CirculationAttribute needDurable) continue;
string methodDescription = needDurable.MethodDescription ?? $"{type.Name}.{method.Name}";
bool Action() => (bool)(method.Invoke(Activator.CreateInstance(type, instanceParams), []) ?? false);
StartTask(Action, methodDescription, needDurable.CirculationTime);
break;
}
}
}
/// <summary>
/// 开启一个方法
/// </summary>
/// <param name="action"></param>
/// <param name="description"></param>
/// <param name="durableTime"></param>
/// <returns></returns>
public virtual async void StartTask(Func<bool> action, string? description = null, int? durableTime = null)
{
int durableTimeValue = durableTime ?? _defaultCirculationTime;
string methodDescription = description ?? action.Method.Name;
CancellationTokenSource cts = new();
PeriodicTimer timer = new(new TimeSpan(0, 0, 0, 0, durableTimeValue));
MessageHandler?.Invoke($"定时器:{methodDescription},已经启动,执行间隔为:{durableTimeValue} 毫秒。");
while (await timer.WaitForNextTickAsync(cts.Token))
{
try
{
var result = action();
if (result) continue;
await cts.CancelAsync();
MessageHandler?.Invoke($"定时器:{methodDescription},主动结束。");
return; // 该return会结束这个线程
}
catch (Exception ex)
{
ExceptionHandler?.Invoke(methodDescription, ex);
}
}
}
}