Quartz 這個任務調度,挺不錯的,就是,創建任務的時候,每次都得定義一個Ijob 類,來執行,比較麻煩。我這邊通過一個簡單的封裝實現對任務的輕鬆調用和實現。
下載地址 : https://download.csdn.net/download/kesshei/12231473
static void Main(string[] args)
{
TaskProcess taskProcess = new TaskProcess("0/5 * * * * ?", "Print");
taskProcess.Start();
TaskProcess bb = new TaskProcess("0/5 * * * * ?", typeof(Print2));
bb.Start();
TaskProcess bbb = new TaskProcess("0/5 * * * * ?", typeof(Print2));
bbb.Start();
Console.ReadLine();
}
兩個參數,一個是Cron表達式,一個是繼承了 ITask的接口類的類名或者類型。
下邊是一個標準的Quartz 任務
/// <summary>
/// 任務
/// </summary>
public class TaskJob : IJob
{
public Task Execute(IJobExecutionContext context)
{
string type = string.Empty;
JobDataMap data = context.JobDetail.JobDataMap;
if (data.ContainsKey("Type"))
{
type = data["Type"].ToString();
}
return Task.Factory.StartNew(() =>
{
TypeFactory.Make(type)?.Run();
});
}
}
任務處理器
public class TaskProcess
{
/// <summary>
/// 任務調度器(單例)
/// </summary>
static IScheduler scheduler = null;
/// <summary>
/// 對象鎖
/// </summary>
static object LockObj = new object();
/// <summary>
/// 內置唯一Key
/// </summary>
string JobKey = Guid.NewGuid().ToString("N");
/// <summary>
/// 內置唯一Key
/// </summary>
string TriggerKey = Guid.NewGuid().ToString("N");
/// <summary>
/// cron表達式
/// </summary>
public string cron { get; set; }
/// <summary>
/// 對象類型
/// </summary>
public string TypeName { get; set; }
/// <summary>
/// 獲取調度器
/// </summary>
/// <returns></returns>
IScheduler GetScheduler()
{
if (scheduler == null)
{
lock (LockObj)
{
if (scheduler == null)
{
StdSchedulerFactory factory = new StdSchedulerFactory();
scheduler = factory.GetScheduler().GetAwaiter().GetResult();
scheduler.Start();
}
}
}
return scheduler;
}
public TaskProcess(string Cron, Type type)
{
this.cron = Cron;
this.TypeName = type.Name;
}
public TaskProcess(string Cron, string TypeName)
{
this.cron = Cron;
this.TypeName = TypeName;
}
public void Start()
{
AddJob(cron, TypeName).GetAwaiter().GetResult();
Console.WriteLine($"{TypeName} 任務啓動!");
}
/// <summary>
/// 增加任務
/// </summary>
/// <returns></returns>
public async Task AddJob(string cron, string typeName)
{
var IScheduler = GetScheduler();
IJobDetail jobDetail = JobBuilder.Create<TaskJob>()
.WithIdentity(JobKey)
.Build();
jobDetail.JobDataMap.Put("Type", typeName);
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(TriggerKey)
.WithCronSchedule(cron)
.ForJob(jobDetail)
.Build();
await IScheduler.ScheduleJob(jobDetail, trigger);
}
/// <summary>
/// 關閉任務
/// </summary>
public void Close()
{
var IScheduler = GetScheduler();
TriggerKey triggerKey = new TriggerKey(TriggerKey);
IScheduler.PauseTrigger(triggerKey);
var unschedule = IScheduler.UnscheduleJob(triggerKey).GetAwaiter().GetResult();
var result = IScheduler.DeleteJob(new JobKey(JobKey)).GetAwaiter().GetResult();
if (unschedule || result)
{
Console.WriteLine("任務關閉成功!");
}
else
{
Console.WriteLine("任務關閉失敗!");
}
}
}
以及,重要的類型工廠
/// <summary>
/// 類型工廠
/// </summary>
public static class TypeFactory
{
static TypeFactory()
{
CollectAllEntityClasses();
}
/// <summary>
/// 類型字典
/// </summary>
static Dictionary<string, Type> Types = new Dictionary<string, Type>();
/// <summary>
/// 收集當前所有實例類名字
/// </summary>
public static void CollectAllEntityClasses()
{
var AS = AppDomain.CurrentDomain.GetAssemblies().ToList();
foreach (var item in AS)
{
var types = item.GetTypes().ToList();
foreach (var type in types)
{
string className = type.Name;
if (typeof(ITask).IsAssignableFrom(type))
{
Types.Add(className, type);
}
}
}
}
/// <summary>
///類型工廠
/// </summary>
/// <returns></returns>
public static ITask Make(Type Type)
{
Type t;
if (Types.TryGetValue(Type.Name, out t))
{
return (ITask)Activator.CreateInstance(t);
}
return null;
}
/// <summary>
///類型工廠
/// </summary>
/// <returns></returns>
public static ITask Make(string Name)
{
Type t;
if (Types.TryGetValue(Name, out t))
{
return (ITask)Activator.CreateInstance(t);
}
return null;
}
/// <summary>
/// 增加一個類型
/// </summary>
/// <param name="Type"></param>
/// <param name="type"></param>
public static void AddType(Type type)
{
if (!Types.ContainsKey(type.Name))
{
Types.Add(type.Name, type);
}
}
}
加上實際繼承的接口類
public interface ITask
{
void Run();
}
以及任意一個 實現的類
class Print2 : ITask
{
public void Run()
{
Console.WriteLine(DateTime.Now.ToString() + " Print2");
}
}
查看具體的結果:
運行效果,符合預期,使用簡單方便。