2011-08-21 19 views
14

Estoy planeando escribir una página ASP.NET para activar el trabajo a pedido. Actualmente, estoy usando la clase SimpleTrigger para activar el trabajo, pero ninguna de las clases __Trigger admite el tipo de objeto como valor en JobParameters y he llegado a mi conocimiento de que el enlace WCF Tcp se usa debajo del gancho para pasar los parámetros al motor de programación de trabajos. Me gustaría saber cómo pasar objetos personalizados (serializables) como parámetros de trabajo. ¡Gracias por tu consejo!Scheduler de cuarzo: ¿Cómo pasar objetos personalizados como JobParameter?

Respuesta

4

Al programar un trabajo puede establecer JobDataMap en el objeto JobDetail y pasarlo a su planificador, hay algunas limitaciones descritas en el quartz.net tutorial. El trabajo puede acceder a los datos a través de:

JobDataMap dataMap = context.JobDetail.JobDataMap; 

Sin embargo yo prefiero acceder a la configuración de mi trabajo, a través de un repositorio inyecta en el trabajo.

+0

Gracias por su respuesta, pero lo que yo estoy buscando es cómo pasar los objetos de aplicación externa. –

+0

Esto es algo que también necesito saber ... sigue buscando – evermean

+0

¿Cómo inyectas tu repositorio sin usar JobDataMap? ¿O es solo el repositorio lo que inyectas? –

24

Hay dos formas de pasar un objeto que puede ser recuperada cuando se ejecuta un trabajo de cuarzo:

pase la instancia en el mapa de datos. Cuando se establece el trabajo, añada su instancia al mapa con una clave de esta manera:

// Create job etc... 
var MyClass _myInstance; 
statusJob.JobDataMap.Put("myKey", _myInstance); 
// Schedule job... 

Recuperar la instancia en el método de trabajo Execute() así:

public void Execute(IJobExecutionContext context) 
     { 
      var dataMap = context.MergedJobDataMap; 
      var myInstance = (MyClass)dataMap["myKey"]; 

O

Agregar la instancia al contexto del planificador cuando configura la tarea, de esta manera:

ISchedulerFactory schedFact = new StdSchedulerFactory(); 
    _sched = schedFact.GetScheduler(); 
    _sched.Start(); 
    // Create job etc... 
    var MyClass _myInstance; 
    _sched.Context.Put("myKey", myInstance); 
    // Schedule job... 

Recuperar la instancia en el método de trabajo Execute() así:

public void Execute(IJobExecutionContext context) 
     { 
      var schedulerContext = context.Scheduler.Context; 
      var myInstance = (MyClass)schedulerContext.Get("myKey"); 
+0

Al usar JobDataMap, ¿cómo se serializa la instancia de MyClass? ¿Tiene que ser atribuido con '[Serializable]'? – Dejan

+0

Dejan, no he usado [Serializable], y mis instancias se recuperan bien. Por lo que puedo decir, la serialización se invoca cuando usa una JobStore persistente en Quartz. Tenga en cuenta que la documentación de Quartz advierte sobre el almacenamiento de tipos no primitivos si se serializa: http://quartz-scheduler.org/documentation/best-practices. Sobre esa base, el ejemplo en mi respuesta puede no serle útil. – hillstuk

2

que estaba teniendo resultados inesperados con la respuesta de hillstuk anteriores en entornos multiproceso. aquí está mi solución utilizando Newtonsoft ... disfrute de

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

Se puede retener la instancia/objeto en el 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(); 

uso

public void Execute(IJobExecutionContext context) 
     { 
JobDataMap dataMap = context.JobDetail.JobDataMap; 
      Class1 class1 = (Class1)dataMap.Get("Class1"); 
string x = class1.name; 
} 
Cuestiones relacionadas