2011-07-20 21 views
5

Necesito ayuda. Estoy intentando averiguar cómo programar trabajos en Quartz.Net. Los trabajos en Quartz corresponden a las tareas en mi aplicación web, que son cada uno aparte de un trabajo en mi aplicación web. Quiero que los usuarios puedan iniciar un trabajo (contexto de aplicación web) bajo demanda y hacer que se ejecute inmediatamente o programar el trabajo en el futuro y, posiblemente, repetir en un intervalo determinado. Sé cómo se logran todos estos elementos en Quartz individualmente, pero me está costando armarlo todo.Programación de trabajos dependientes en Quartz.Net

Por ejemplo, en mi aplicación web, puedo tener un trabajo con varias tareas, en un orden específico. Quiero poder programar estas tareas en cuarzo para que se ejecuten en el mismo orden determinado en mi aplicación web. ¿Alguien tiene idea de cómo hacer esto? He leído en la documentación de Quartz diciendo que almacene el próximo trabajo en el JobDataMap, simplemente luchando con él.

Actualmente estoy esperando para crear trabajos de Quartz hasta que un usuario solicite programar el trabajo o ejecutarlo. ¿Crees que debería crear el trabajo y activar la creación de la tarea en la aplicación web y luego extraer esa información del objeto de la tarea para programar en Quartz?

Respuesta

4

En el segundo párrafo: si lo entiendo correctamente, tiene un conjunto de trabajos, desde los cuales el usuario puede seleccionar y poner en cierto orden de ejecución. Lo abordaría creando una instancia de trabajo de cada tipo de trabajo seleccionado por el usuario. Para conservar el orden de los trabajos, puede almacenar el nombre de grupo y el nombre de trabajo del próximo trabajo en el JobDataMap del trabajo anterior. Luego puede tener un JobListener genérico, que está registrado en todos los trabajos. El oyente recibirá una notificación cuando se ejecute un trabajo y se le pasará el paquete de trabajo como argumento. JobListener puede enumerar el JobDataMap del trabajo que acaba de ejecutarse. Si encuentra un par de clave-valor con la clave "nextjobname", JobListener consultará el planificador para este trabajo. Una referencia al planificador de también disponible en el paquete de trabajo. Si el planificador devuelve una instancia de JobDetail para el nombre de pila, JobListener la ejecutará, recibirá una notificación cuando se complete y así sucesivamente hasta que llegue a un trabajo con "nextjobname" en JobDataMap.
Como alternativa, si no desea tener oyentes de trabajo, puede tener una clase de trabajo base que implemente esta funcionalidad. Todos sus trabajos derivarán de esta clase y anulará su método de ejecución virtual. Puede llamar a base. Ejecutar (contexto) justo antes de que regrese la implementación principal.

public class Basejob : IJob 
{ 
    public virtual void Execute(JobExecutionContext context) 
    { 
     string nextJob = context.MergedJobDataMap["nextjobname"]; 
     JobDetail nextjob = context.Scheduler.GetJobDetail(context.MergedJobDataMap["nextjobname"], 
              context.MergedJobDataMap["nextjobgroupname"]); 
     if(nextjob != null) 
     { 
      context.Scheduler.ScheduleJob(nextjob, new SimpleTrigger(nextjob.Name + "trigger")); // this will fire the job immediately 
     } 
    } 
} 

public class MyJob : BaseJob 
{ 
    public override void Execute(JobExecutionContext context) 
    { 
     //do work 
     base.Execute(context); 
    } 
} 
+0

Esto tiene sentido. ¿Tiene algún ejemplo de JobListener o clase de trabajo básica? – M4V3R1CK

+0

Otra pregunta rápida: ¿cómo hago para asignar triggers a los trabajos que se ejecutan a través del oyente? Según tengo entendido, para programar un trabajo, debe pasar solo un desencadenante (con un trabajo asociado) o un activador y un trabajo. – M4V3R1CK

+0

En caso de que alguien se esté preguntando, _scheduler.AddJob (trabajo JobDetail, bool Reemplazar) le permite agregar trabajos al almacén de datos sin un activador asociado ... DUHHHHHHHHHHHHHHHHHHH – M4V3R1CK

10

Lo que se necesita es la clase JobChainingJobListener, que está ahí para ayudar a crear una cadena de ejecución de los trabajos en un orden específico que desee ..

using System; 
using System.Text; 
using Quartz; 
using Quartz.Impl; 
using Quartz.Impl.Calendar; 
using Quartz.Listener; 
using Quartz.Impl.Matchers; 
using System.Threading; 

namespace QuartzNET.Samples 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // Create RAMJobStore instance 
      DirectSchedulerFactory.Instance.CreateVolatileScheduler(5); 
      ISchedulerFactory factory = DirectSchedulerFactory.Instance; 

      // Get scheduler and add object 
      IScheduler scheduler = factory.GetScheduler();   

      StringBuilder history = new StringBuilder("Runtime History: "); 
      scheduler.Context.Add("History", history); 

      JobKey firstJobKey = JobKey.Create("FirstJob", "Pipeline"); 
      JobKey secondJobKey = JobKey.Create("SecondJob", "Pipeline"); 
      JobKey thirdJobKey = JobKey.Create("ThirdJob", "Pipeline"); 

      // Create job and trigger 
      IJobDetail firstJob = JobBuilder.Create<FirstJob>() 
             .WithIdentity(firstJobKey) 
             //.StoreDurably(true) 
             .Build(); 

      IJobDetail secondJob = JobBuilder.Create<SecondJob>() 
             .WithIdentity(secondJobKey)          
             .StoreDurably(true)          
             .Build(); 

      IJobDetail thirdJob = JobBuilder.Create<ThirdJob>() 
             .WithIdentity(thirdJobKey) 
             .StoreDurably(true) 
             .Build(); 

      ITrigger firstJobTrigger = TriggerBuilder.Create() 
              .WithIdentity("Trigger", "Pipeline") 
              .WithSimpleSchedule(x => x 
               .WithMisfireHandlingInstructionFireNow() 
               .WithIntervalInSeconds(5)  
               .RepeatForever()) 
              .Build(); 

      JobChainingJobListener listener = new JobChainingJobListener("Pipeline Chain"); 
      listener.AddJobChainLink(firstJobKey, secondJobKey); 
      listener.AddJobChainLink(secondJobKey, thirdJobKey);    

      scheduler.ListenerManager.AddJobListener(listener, GroupMatcher<JobKey>.GroupEquals("Pipeline")); 

      // Run it all in chain 
      scheduler.Start(); 
      scheduler.ScheduleJob(firstJob, firstJobTrigger); 
      scheduler.AddJob(secondJob, false, true); 
      scheduler.AddJob(thirdJob, false, true); 

      Console.ReadLine(); 
      scheduler.Shutdown(); 
      Console.WriteLine("Scheduler shutdown."); 
      Console.WriteLine(history); 
      Console.ReadLine(); 
     } 
    } 

    class FirstJob : IJob 
    { 
     public void Execute(IJobExecutionContext context) 
     { 
      var history = context.Scheduler.Context["History"] as StringBuilder; 
      history.AppendLine(); 
      history.AppendFormat("First {0}", DateTime.Now);    
      Console.WriteLine("First {0}", DateTime.Now); 
     } 
    } 

    class SecondJob : IJob 
    { 
     public void Execute(IJobExecutionContext context) 
     { 
      var history = context.Scheduler.Context["History"] as StringBuilder; 
      history.AppendLine(); 
      history.AppendFormat("Second {0}", DateTime.Now); 
      Console.WriteLine("Second {0}", DateTime.Now);    
     } 
    } 

    class ThirdJob : IJob 
    { 
     public void Execute(IJobExecutionContext context) 
     { 
      var history = context.Scheduler.Context["History"] as StringBuilder; 
      history.AppendLine(); 
      history.AppendFormat("Third {0}", DateTime.Now); 
      Console.WriteLine("Third {0}", DateTime.Now); 
      Console.WriteLine(); 
     } 
    } 
} 
Cuestiones relacionadas