110 lines
3.6 KiB
C#
110 lines
3.6 KiB
C#
using System.Reflection;
|
||
|
||
namespace CirculateTool;
|
||
/*
|
||
* 作者:菻蔃
|
||
* 版本时间:2023年04月15日
|
||
*
|
||
* 注意配合特性使用
|
||
*
|
||
*/
|
||
|
||
/// <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);
|
||
}
|
||
}
|
||
}
|
||
} |