<update>[important]添加按时执行任务的支持

This commit is contained in:
葛林强 2024-06-21 09:30:10 +08:00
parent e340de9a51
commit e86cc463e1
17 changed files with 177 additions and 24 deletions

View File

@ -1,4 +1,4 @@
namespace CirculateTool;
namespace CirculateTool.Attribute;
/// <summary>
/// 一个类里面的方法加上这个特性就表示需要被循环执行
@ -10,7 +10,7 @@
/// <param name="methodDescription">方法描述</param>
/// <param name="tags">方法描述</param>
[AttributeUsage(AttributeTargets.All)]
public class CirculationAttribute(string? methodDescription = null, int circulationTime = 500, string[]? tags = null) : Attribute
public class CirculationAttribute(string? methodDescription = null, int circulationTime = 500, string[]? tags = null) : System.Attribute
{
/// <summary>

View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CirculateTool.Attribute;
/// <summary>
/// 在指定时间执行的任务
/// </summary>
/// <param name="times"></param>
/// <param name="methodDescription"></param>
/// <param name="tags"></param>
/// <remarks>
/// 只能加载公共 void 方法上,
/// 不得与<see cref="CirculationAttribute"/>同时使用,若同时使用则此项不生效
/// </remarks>
[AttributeUsage(AttributeTargets.Method)]
public class CirculationTimeAttribute(string[] times, string? methodDescription = null, string[]? tags = null) : System.Attribute
{
/// <summary>
/// 定时执行的时间
/// </summary>
/// <example>12:00</example>
/// <remarks>
/// 格式必须为HH:mm例如12:00其他格式将无效
/// </remarks>
public string[] Times { get; } = times;
/// <summary>
/// 描述
/// </summary>
public string? MethodDescription { get; } = methodDescription;
/// <summary>
/// 标签
/// </summary>
public string[]? Tags { get; } = tags;
public override string ToString()
{
return string.Join(",", Times);
}
}

View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CirculateTool.Entity;
/// <summary>
/// 按时执行的任务的定时类
/// </summary>
internal class TimeTask
{
/// <summary>
/// 执行任务的时间
/// </summary>
public string? ExecuteTime { get; set; }
/// <summary>
/// 任务
/// </summary>
public Action? Action { get; set; }
/// <summary>
/// 描述
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 是否已经执行
/// </summary>
public bool IsRun { get; set; } = false;
}

View File

@ -1,4 +1,6 @@
using System.Reflection;
using CirculateTool.Attribute;
using CirculateTool.Entity;
namespace CirculateTool;
/*
@ -14,6 +16,10 @@ namespace CirculateTool;
/// </summary>
public class StartCirculation
{
/// <summary>
/// 指定时间执行的方法类
/// </summary>
private static List<TimeTask> _timeTasks = [];
/// <summary>
/// 触发的异常
@ -39,7 +45,7 @@ public class StartCirculation
/// </summary>
/// <param name="assembly"></param>
/// <param name="instanceParams"></param>
public virtual void StartAssemblyCirculation(Assembly assembly, object[]? instanceParams = null)
public void StartAssemblyCirculation(Assembly assembly, object[]? instanceParams = null)
{
Type[] types = assembly.GetTypes();
if (types.Length == 0) return;
@ -65,20 +71,45 @@ public class StartCirculation
var methods = type.GetMethods();
foreach (var method in methods)
{
var attributes = method.GetCustomAttributes(false);
foreach (var attribute in attributes)
object[] attributes = method.GetCustomAttributes(false);
if(attributes.Length == 0) continue;
foreach (object 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;
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();
}
/// <summary>
/// 开启一个方法
/// 开启一个方法 ---- 隔一定时间执行一次
/// </summary>
/// <param name="action"></param>
/// <param name="description"></param>
@ -107,4 +138,42 @@ public class StartCirculation
}
}
}
/// <summary>
/// 执行按时间执行的任务
/// </summary>
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<Task> 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]);
}
}
}

View File

@ -1,4 +1,4 @@
using CirculateTool;
using CirculateTool.Attribute;
using WcsMain.Common;
using WcsMain.EquipOperation;

View File

@ -1,4 +1,4 @@
using CirculateTool;
using CirculateTool.Attribute;
using WcsMain.Business.CommonAction;
namespace WcsMain.Business.CirculationTask.CommonCirculation;
@ -49,7 +49,7 @@ public class DataClear(ClearData clearData)
// 清理扫码记录表 -- 保留多少天
int clearScanRecord = clearData.ClearScanRecordData(15);
ConsoleLog.Tip(clearScanRecord > 0, $"[数据清理]清理扫码记录:{apiWmsTaskCount}");
ConsoleLog.Tip(clearScanRecord > 0, $"[数据清理]清理扫码记录:{clearScanRecord}");
}
catch (Exception ex)

View File

@ -1,4 +1,4 @@
using CirculateTool;
using CirculateTool.Attribute;
using WcsMain.EquipOperation.Convey;
namespace WcsMain.Business.CirculationTask.CommonCirculation;

View File

@ -1,4 +1,4 @@
using CirculateTool;
using CirculateTool.Attribute;
using WcsMain.Business.Convey.HistoryDataHandler;
using WcsMain.DataBase.Dao;
using WcsMain.DataBase.TableEntity;

View File

@ -1,4 +1,4 @@
using CirculateTool;
using CirculateTool.Attribute;
using LedSimple;
using WcsMain.Common;
using WcsMain.DataBase.Dao;

View File

@ -1,4 +1,4 @@
using CirculateTool;
using CirculateTool.Attribute;
using WcsMain.Common;
using WcsMain.DataBase.Dao;
using WcsMain.DataBase.TableEntity;

View File

@ -1,4 +1,4 @@
using CirculateTool;
using CirculateTool.Attribute;
using WcsMain.Business.CommonAction;
using WcsMain.Common;
using WcsMain.DataBase.Dao;

View File

@ -1,4 +1,4 @@
using CirculateTool;
using CirculateTool.Attribute;
using WcsMain.Business.CommonAction;
using WcsMain.Common;
using WcsMain.DataBase.Dao;

View File

@ -1,4 +1,4 @@
using CirculateTool;
using CirculateTool.Attribute;
using WcsMain.Business.CommonAction;
using WcsMain.Common;
using WcsMain.DataBase.Dao;

View File

@ -1,4 +1,4 @@
using CirculateTool;
using CirculateTool.Attribute;
using WcsMain.Business.CommonAction;
using WcsMain.DataBase.Dao;
using WcsMain.DataBase.TableEntity;

View File

@ -1,4 +1,4 @@
using CirculateTool;
using CirculateTool.Attribute;
namespace WcsMain.Business.CirculationTask.StackerConvey;

View File

@ -1,4 +1,4 @@
using CirculateTool;
using CirculateTool.Attribute;
using WcsMain.ExtendMethod;
using WcsMain.DataBase.Dao;
using WcsMain.DataBase.TableEntity;

View File

@ -1,4 +1,5 @@
using Autofac;
using CirculateTool.Attribute;
using CirculateTool;
using WcsMain.WcsAttribute.AutoFacAttribute;