3 votes

Définition d'un déclencheur Quartz.NET pour qu'il se déclenche sur une instance d'objet spécifique

Comment puis-je obtenir Quartz pour déclencher un trigger sur un objet déjà créé et initialisé ?

par exemple

public class Foo : IJob
{
    public Foo ( items de configuration ... ) { }
}

// Code d'appel...
Foo f = new Foo( /* Constructeur non vide */ );
Schedular sched = new SchedulerFactory().GetScheduler();
JobDetail jD = new JobDetail("fooDetail", null typeof(Foo));
Trigger trig = TriggerUtils.MakeSecondlyTrigger(15);
sched.ScheduleJob( jD, trig );
sched.Start();

Comme foo n'a pas de constructeur sans arguments, Quartz.NET rencontre des problèmes pour instancier le Job et l'exécuter. Y a-t-il un moyen de faire en sorte que Quartz déclenche l'instance de Foo, f ?

Veuillez me pardonner si je manque un fait fondamental sur Quartz et son utilisation.

3voto

Jehof Points 14720

Vous pourriez implémenter votre propre Quartz.Spi.IJobFactory (qui utilise un conteneur DI) pour définir comment les jobs sont créés et initialisés. Quartz ne permet pas de planifier des jobs déjà initialisés.

Voici un JobFactory qui utilise Unity pour créer des jobs. Dans le conteneur, vous pourriez enregistrer le type de job et définir comment le conteneur doit construire le job et résoudre les dépendances du job.

public class UnityJobFactory : IJobFactory {

    public UnityJobFactory(IUnityContainer container) {
        Container = container;
    }

    public IUnityContainer Container { get; private set; }

    public IJob NewJob(TriggerFiredBundle bundle) {
        try {
            return Container.Resolve(bundle.JobDetail.JobType, null) as IJob;
        }
        catch (Exception exception) {
            throw new SchedulerException("Erreur lors de la création du nouveau job", exception);
        }
    }
}

0voto

TK. Points 9976

La documentation de Quartz.NET indique: (en très petit!)

Chaque fois que le planificateur exécute le travail, il crée une nouvelle instance de la classe avant d'appeler sa méthode Execute(..). Une des conséquences de ce comportement est que les travaux doivent avoir un constructeur sans argument.

Ainsi, avoir des travaux avec des constructeurs complexes est une mauvaise idée!

Temps pour le Plan B:

J'ai créé un 'Travailleur' principal. Ce travail regardait dans context.JobDetail.JobDataMap pour déterminer quel type de tâche devait vraiment être exécutée. La fonction Execute ressemblait un peu à ceci:

public void Execute( JobExecutionContext context )
{
    JobDataMap dataMap = context.JobDetail.JobDataMap;

    // Exécuter la tâche stockée
    Foo tâcheÀExécuter = dataMap["Tâche"] as Foo;
    if ( tâcheÀExécuter != null )
    {
        tâcheÀExécuter.Execute();
    }           
}

Cela permet à la Tâche d'être créée avant la planification et à l'instance de la tâche d'être exécutée chaque fois que le Travailleur principal se déclenche par exemple:

JobDetail détail = new JobDetail( "foo", null, typeof( TâchePrincipale) );
détail.JobDataMap["Tâche"] = tâche;

Je suis sûr que cela viole certaines règles maîtresses de Quartz, mais cela signifie au moins que je peux faire ce qui doit être fait!

0voto

Ant Points 248

Ne mettez rien dans la classe implémentant IJob, créez une classe qui implémente un IJobListener et faites-la écouter le travail de votre groupe.

var myJobListener = new YourClassImplementingIJobListener(param1, param2);
sched.ListenerManager.AddJobListener(myJobListener,GroupMatcher.GroupEquals("myJobGroup"));

Plus d'informations à ce sujet ici http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/trigger-and-job-listeners.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X