通过反射加载任务调度
需求:
- 因为有些任务需要进行各种定时操作,因此将 Quartz.Net 简单封装了一下使用;
- 希望通过上传 dll 来进行每个任务的调度,所以写了个反射调度示例;
Program.cs
using Serilog;
using Serilog.Core;
using Quartz;
using System.Reflection;
_net.SimpleScheduler scheduler = _net.SimpleScheduler.Create();
List<IWorkItem> workItems = GetWorkItems();
foreach (var item in workItems)
{
scheduler.AddJob(item);
}
scheduler.Start();
Console.ReadLine();
static List<IWorkItem> GetWorkItems()
{
var assembly = Assembly.GetExecutingAssembly();
List<IWorkItem> workItems = new List<IWorkItem>();
foreach (var item in assembly.ExportedTypes)
{
Type? type = item.GetInterface(nameof(IWorkItem));
if (type != null && type.Name.Equals(nameof(IWorkItem)))
{
ConstructorInfo? constructorInfo = item.GetConstructor(BindingFlags.Public | BindingFlags.Instance, Type.EmptyTypes);
var workItem = constructorInfo?.Invoke(Array.Empty<object>()) as IWorkItem;
workItems.Add(item: workItem!);
}
}
return workItems;
}
public interface IWorkItem : IJob
{
ITrigger Trigger { get; set; }
IJobDetail JobDetail { get; set; }
JobKey JobKey { get; set; }
}
public class MyWork : IWorkItem
{
public ITrigger Trigger { get; set; }
public IJobDetail JobDetail { get; set; }
public JobKey JobKey { get; set; }
private static Logger? _log = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
public MyWork()
{
Trigger = TriggerBuilder.Create().WithDailyTimeIntervalSchedule(d => d.WithIntervalInSeconds(3)).StartNow().WithIdentity("trigger", "test").Build();
JobDetail = JobBuilder.Create(this.GetType()).WithIdentity("jobDetail", "test").Build();
JobKey = JobDetail.Key;
}
public Task Execute(IJobExecutionContext context)
{
_log.Information("MyJob current date {A}", DateTime.Now.ToLongTimeString());
return Task.CompletedTask;
}
}
SimpleScheduler.cs
namespace _net
{
/// <summary>
/// 基于 Quartz.Net 简单的封装
/// </summary>
public class SimpleScheduler
{
private Quartz.ISchedulerFactory _schedulerFactory;
private Quartz.IScheduler _scheduler;
public SimpleScheduler()
{
_schedulerFactory = new Quartz.Impl.StdSchedulerFactory();
_scheduler = _schedulerFactory.GetScheduler().ConfigureAwait(false).GetAwaiter().GetResult();
}
public static SimpleScheduler Create()
{
return new SimpleScheduler();
}
public SimpleScheduler AddJob(IWorkItem workItem)
{
_scheduler.ScheduleJob(workItem.JobDetail, workItem.Trigger);
return this;
}
public void Start()
{
_scheduler.Start();
}
public void Shutdown()
{
if (_scheduler != null)
{
_scheduler.Shutdown();
}
}
}
}