情况
我已经使用 this DI 集成示例实现了 Quartz。 该配置可确保应用程序启动时,作业和触发器会覆盖现有作业和触发器。
问题
但是当我想重命名作业或触发器时,它不会覆盖现有记录并添加新记录。因此,相同的作业或触发器(仅具有不同的名称)在数据库中出现两次。
所需的解决方案
如果我可以在
scheduler.clear()
函数中添加作业和触发器之前触发 services.addQuartz
,那么(在我看来)这将是所需的解决方案。但我似乎不知道如何使用 DI 集成来做到这一点。
我找到了!在
AddQuartz
中获取调度程序并传递属性,只需在函数中初始化,如下所示:
services.AddQuartz(options =>
{
options.InterruptJobsOnShutdown = false;
options.InterruptJobsOnShutdownWithWait = true; // only when services.AddQuartzHostedService options.WaitForJobsToComplete is also true
options.UsePersistentStore(s =>
{
s.UseProperties = true;
s.UseSqlServer(sqlServer =>
{
sqlServer.ConnectionString = configuration["ConnectionString"];
sqlServer.TablePrefix = "Qrtz_";
});
s.UseNewtonsoftJsonSerializer();
});
try
{
Task.Run(async () =>
{
// Clear DB before adding the jobs and triggers
ISchedulerFactory schedulerFactory = new StdSchedulerFactory(options.Properties);
IScheduler scheduler = await schedulerFactory.GetScheduler();
await scheduler.Clear();
await scheduler.Shutdown();
}).Wait();
}
catch (AggregateException)
{
// Do nothing, this happens when the application is starting for the first time and the tables are not created yet
}
if (assemblies?.Any() == true)
{
foreach (Assembly assembly in assemblies)
{
IEnumerable<Type> jobTypes = assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IJobExtenstions)));
foreach (Type jobType in jobTypes)
{
IJobExtenstions jobInstance = FormatterServices.GetUninitializedObject(jobType) as IJobExtenstions;
options.AddJob(jobInstance.GetType(), jobInstance.JobKey);
options.AddTrigger(jobInstance.TriggerConfigurator);
}
}
};
});