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;
}