【问题标题】:Quartz Scheduler: How to pass custom objects as JobParameter?Quartz Scheduler:如何将自定义对象作为 JobParameter 传递?
【发布时间】:2011-08-21 11:24:23
【问题描述】:

我打算编写一个 ASP.NET 页面来按需触发作业。目前,我正在使用 SimpleTrigger 类来触发作业,但 __Trigger 类都不支持对象类型作为 JobParameters 中的值,并且据我所知,WCF Tcp 绑定在挂钩下用于将参数传递给作业调度引擎。我想知道如何将自定义对象(可序列化)作为作业参数传递。 谢谢你的建议!

【问题讨论】:

    标签: c# asp.net c#-3.0 quartz.net


    【解决方案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");
    

    【讨论】:

    • 在使用JobDataMap时,MyClass实例是如何被序列化的?是否需要使用[Serializable] 进行归属?
    • Dejan,我没有使用[Serializable],我的实例检索正常。据我所知,当您在 Quartz 中使用持久 JobStore 时会调用序列化。请注意,Quartz 文档警告不要在序列化时存储非原始类型:quartz-scheduler.org/documentation/best-practices。在此基础上,我回答中的示例可能对您没有用。
    • 这出奇的好。我能够将 MQTTNet 客户端实例传递给作业!太好了!
    【解决方案2】:

    当您安排作业时,您可以在 JobDetail 对象上设置 JobDataMap 并将其传递给您的调度程序,quartz.net tutorial 中描述了一些限制。该作业可以通过以下方式访问数据:

    JobDataMap dataMap = context.JobDetail.JobDataMap;
    

    但是我更喜欢通过注入到作业中的存储库来访问我的作业配置。

    【讨论】:

    • 感谢您的回复,但我正在寻找的是如何从外部应用程序传递对象。
    • 这也是我需要知道的……还在搜索中
    • 如何在不使用 JobDataMap 的情况下注入存储库?还是只是你注入的 repo?
    【解决方案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;
      }
      

      【讨论】:

        【解决方案5】:

        我按照以下方式传递了对象

        JobDetail job1 = JobBuilder.newJob(JobAutomation.class)
                        .usingJobData("path", path)
                        .withIdentity("job2", "group2").build();
        
                CronTrigger trigger1 = TriggerBuilder.newTrigger()
                        .withIdentity("cronTrigger2", "group2")
                        .withSchedule(CronScheduleBuilder.cronSchedule("40 27 11 * * ?"))
                        .build();
        

        通过以下代码行获取jobdatamap

        JobDataMap dataMap = context.getJobDetail().getJobDataMap();
        String path =dataMap.getString("path");
        

        【讨论】:

        • JobDataMap dataMap = context.getMergedJobDataMap();更可取
        猜你喜欢
        • 1970-01-01
        • 2012-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多