using System.Reflection; using CirculateTool.Attribute; using CirculateTool.Entity; namespace CirculateTool; /* * 作者:菻蔃 * 版本时间:2023年04月15日 * * 注意配合特性使用 * */ /// /// 定时任务类 /// public class StartCirculation { /// /// 指定时间执行的方法类 /// private static List _timeTasks = []; /// /// 触发的异常 /// public event ExceptionHandlerEvent? ExceptionHandler; public delegate void ExceptionHandlerEvent(string methodDescription, Exception ex); /// /// 显示相关信息 /// public event MessageHandlerEvent? MessageHandler; public delegate void MessageHandlerEvent(string message); /// /// 默认的循环时间 /// private readonly int _defaultCirculationTime = 500; /// /// 启动一个程序集里面带有的类里面的定时方法 /// /// /// public 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; } } } /// /// 开启一个实例里面所有已经添加了特性的方法 /// /// /// public virtual void StartTask(Type type, object[]? instanceParams = null) { var methods = type.GetMethods(); foreach (var method in methods) { object[] attributes = method.GetCustomAttributes(false); if(attributes.Length == 0) continue; foreach (object attribute in attributes) { if(attribute == default) continue; /* 定时执行的任务 */ if(attribute is CirculationAttribute needDurable) { string methodDescription = needDurable.MethodDescription ?? $"{type.Name}.{method.Name}"; bool Action() => (bool)(method.Invoke(Activator.CreateInstance(type, instanceParams), []) ?? false); StartTask(Action, methodDescription, needDurable.CirculationTime); break; } /* 每天指定时间执行 */ if (attribute is CirculationTimeAttribute timeCirculate) { string methodDescription = timeCirculate.MethodDescription ?? $"{type.Name}.{method.Name}"; MessageHandler?.Invoke($"定时器任务:{methodDescription},已经添加,执行时间为:{timeCirculate}"); foreach (var time in timeCirculate.Times) { _timeTasks.Add(new TimeTask { ExecuteTime = time, Action = () => method.Invoke(Activator.CreateInstance(type, instanceParams), []), Description = methodDescription, IsRun = false }); } } /* END */ } } /* 执行按时执行的任务 ---- 方法内判断,若没有此类方法则不会执行 */ StartTimeTask(); } /// /// 开启一个方法 ---- 隔一定时间执行一次 /// /// /// /// /// public virtual async void StartTask(Func 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); } } } /// /// 执行按时间执行的任务 /// public virtual async void StartTimeTask() { if(_timeTasks.Count == 0) return; CancellationTokenSource cts = new(); PeriodicTimer timer = new(new TimeSpan(0, 0, 0, 10, 0)); while (await timer.WaitForNextTickAsync(cts.Token)) { string timeStr = DateTime.Now.ToString("HH:mm"); List taskList = []; taskList.Add(Task.Factory.StartNew(() => { foreach (var task in _timeTasks) { if (task.ExecuteTime != timeStr) { task.IsRun = false; // 当时刻不匹配时,重置任务状态 } if (task.ExecuteTime == timeStr && !task.IsRun) // 当时间匹配且任务未执行时,执行任务 { try { task.Action?.Invoke(); task.IsRun = true; } catch (Exception ex) { ExceptionHandler?.Invoke(task.Description ?? task.Action!.Method.Name, ex); } } } })); Task.WaitAll([.. taskList]); } } }