Quartz Scheduler: Как передать пользовательские объекты в качестве JobParameter?
Я планирую написать страницу ASP.NET для запуска задания по требованию. В настоящее время я использую класс SimpleTrigger для запуска задания, но ни один из классов __Trigger не поддерживает тип объекта как значение в JobParameters, и мне стало известно, что привязка WCF Tcp используется под крюком для передачи параметров механизму планирования заданий. Я хотел бы знать, как передать пользовательский объект (serializable) в качестве параметров задания.
Спасибо за ваш совет!
Ответы
Ответ 1
Есть два способа передать объект, который можно получить при выполнении задания Quartz:
Передайте экземпляр на карте данных. Когда вы установите задание вверх, добавьте свой экземпляр на карту с помощью такого ключа:
// Create job etc...
var MyClass _myInstance;
statusJob.JobDataMap.Put("myKey", _myInstance);
// Schedule job...
Получить экземпляр в методе задания Execute()
следующим образом:
public void Execute(IJobExecutionContext context)
{
var dataMap = context.MergedJobDataMap;
var myInstance = (MyClass)dataMap["myKey"];
ИЛИ
Добавьте экземпляр в контекст планировщика при установке задания вверх, например:
ISchedulerFactory schedFact = new StdSchedulerFactory();
_sched = schedFact.GetScheduler();
_sched.Start();
// Create job etc...
var MyClass _myInstance;
_sched.Context.Put("myKey", myInstance);
// Schedule job...
Получить экземпляр в методе задания Execute()
следующим образом:
public void Execute(IJobExecutionContext context)
{
var schedulerContext = context.Scheduler.Context;
var myInstance = (MyClass)schedulerContext.Get("myKey");
Ответ 2
Когда вы планируете задание, вы можете установить JobDataMap
на JobDetail
и передать это своему планировщику, есть некоторые ограничения, описанные в учебнике quartz.net. Задание может получить доступ к данным через:
JobDataMap dataMap = context.JobDetail.JobDataMap;
Однако я предпочитаю доступ к моей конфигурации заданий через репозиторий, введенный в задание.
Ответ 3
У меня были неожиданные результаты с ответом Hillstuk выше в многопоточных средах.
Здесь мое решение с использованием Newtonsoft... Наслаждайтесь
public void InitJob() {
MyClass data = new MyClass {Foo = "Foo fighters"};
/* a unique identifier for demonstration purposes.. Use your own concoction here. */
int uniqueIdentifier = new Random().Next(int.MinValue, int.MaxValue);
IJobDetail newJob = JobBuilder.Create<MyAwesomeJob>()
.UsingJobData("JobData", JsonConvert.SerializeObject(data))
.WithIdentity($"job-{uniqueIdentifier}", "main")
.Build();
}
/* the execute method */
public class MyAwesomeJob : IJob
{
public void Execute(IJobExecutionContext context)
{
var jobData = JsonConvert.DeserializeObject<MyClass>(context.JobDetail.JobDataMap.GetString("JobData"));
}
}
/* for completeness */
public class MyClass {
string Foo { get; set; }
}
Ответ 4
Вы можете поместить свой экземпляр/объект в файл IJobDetail.
JobDataMap m = new JobDataMap();
m.Put("Class1", new Class1(){name="xxx"});
IJobDetail job = JobBuilder.Create<Job>()
.WithIdentity("myJob", "group1")
.UsingJobData(m)//class object
.UsingJobData("name2", "Hello World!")
.Build();
использование
public void Execute(IJobExecutionContext context)
{
JobDataMap dataMap = context.JobDetail.JobDataMap;
Class1 class1 = (Class1)dataMap.Get("Class1");
string x = class1.name;
}