代码之家  ›  专栏  ›  技术社区  ›  loki

如何使用Quartz.Net中的NameValueCollection访问任何作业属性?

  •  1
  • loki  · 技术社区  · 14 年前

    我有一个关于Quartz.net的大项目。我被创造了一些工作来完成一些任务。所以我做了一个总结项目来了解我。我有一份工作。我想将一些值解析为job的属性。在执行时,作业需要这些属性。但我不能那样做。请不要说“为什么不使用‘JobDetail.JobDataMap’?”我需要以下结构:

    enter image description here

    查找工作基础:

     public abstract class JobBase : MarshalByRefObject, IStatefulJob
    {
        void IJob.Execute(JobExecutionContext context)
        {
            this.Execute();
        }
    
        protected abstract void Execute();
    }
    

    也测试.cs(这是我的工作!)

    测试.cs:

     public class Test : JobBase
    {
    
        public string FileName { get; set; }
    
        public string Ip { get; set; }
    
    
        protected override void Execute()
        {
            Ping ping = new Ping();
            PingReply pingReply = ping.Send(Ip);
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(FileName, true))
            {
                file.WriteLine(pingReply.Address);
            }  
        }
    }
    

    我的项目开始时间表:

       private void btnProperties_Click(object sender, EventArgs e)
        {
            ISchedulerFactory schedfabrikayeni;
            IScheduler schedyeni;
            JobDetail job;
            CronTrigger trigeryeni;
            NameValueCollection properties = new NameValueCollection();
            properties["FileName"] = @"C:\temp\pingresult.txt";
            properties["Ip"] = "192.168.16.14";
    
    
            schedfabrikayeni = new StdSchedulerFactory(properties);
            schedyeni = schedfabrikayeni.GetScheduler();
            job = new JobDetail("myJob", null, typeof(Test));
    
            JobDataMap map = new JobDataMap();
            map.Put("msg", "Your remotely added job has executed!");
            job.JobDataMap = map;
            string cronExpressiontxt = string.Empty;
            //0 0 12 1 4 ? *
            cronExpressiontxt = "0 0/1 * 1/1 * ? *";
            trigeryeni = new CronTrigger("triger1", null, "myJob", null, cronExpressiontxt);
    
            schedyeni.ScheduleJob(job, trigeryeni);
            schedyeni.Start();
        }
    

    但我的Ip为空我的FileName为空。如何使用以下用法设置属性:

      NameValueCollection properties = new NameValueCollection();
            properties["FileName"] = @"C:\temp\pingresult.txt";
            properties["Ip"] = "192.168.16.14";
    
    
            schedfabrikayeni = new StdSchedulerFactory(properties);
    
    3 回复  |  直到 14 年前
        1
  •  1
  •   dsum    14 年前

    我必须同意@jvilalta和@sgmoore的观点,您需要使用JobDataMap来存储有状态的数据。以下是我如何使用JobDataMap属性的示例:

        protected override void ExecuteWorker(IJobExecutionContext context)
        {
            try
            {
                SomeProcessor someProcessor;
    
                // If the JobDataMap doesn't contain the initialized key yet, then this job hasn't been run before.
                // Initialize state data if this is the case; otherwise, get state data from the JobDataMap.
                if (!context.JobDetail.JobDataMap.Contains(QUARTZ_KEY_PROCESSOR))
                {
                    someProcessor = someProcessorFactory.Create();
    
                    if (someProcessor == null)
                        return;
    
                    context.JobDetail.JobDataMap[QUARTZ_KEY_PROCESSOR] = someProcessor;
                }
                else
                {
                    someProcessor = (someProcessor)context.JobDetail.JobDataMap[QUARTZ_KEY_PROCESSOR];
                }
    
                ExecuteETL(someProcessor, DateTime.MaxValue);
            }
            catch (Exception e)
            {
                m_log.Fatal("Scheduled job execution failed.", e);
                // This method can only throw a JobExecutionException.
                // http://quartznet.sourceforge.net/tutorial/lesson_3.html
                throw new JobExecutionException(e);
            }
        }
    
        2
  •  0
  •   sgmoore    14 年前

    你是从哪里想到这会奏效的?我从来没有见过这样的例子。

    我可能错了,但据我所知,传递给调度程序的NameValueCollection属性是用于配置调度程序本身工作方式的设置。例如,如果您希望调度程序使用sql数据库,您可以将quartz.jobStore.type的值设置为“quartz.Impl.AdoJobStore.JobStoreTX,quartz”。

    我假设,如果您传递了调度程序不知道的任何额外属性,它们就会被忽略。

    特别是,似乎没有任何方法可以访问调度器上的属性,这再次表明只需要/用于初始化调度器。

    请不要说“为什么不使用‘JobDetail.JobDataMap’?”

    JobDataMap似乎正是为了这个目的而设计的。如果有什么原因不适合你,你最好解释一下 为什么? 它不起作用。

        3
  •  0
  •   jvilalta    14 年前

    您可以通过实现自定义调度程序工厂和/或自定义作业工厂来实现这一点。默认的计划程序和作业工厂不支持像您描述的那样设置作业属性。正如@sgmoore所指出的,JobDataMap是向作业传递参数的正确方式。

    FWIW,您现有的代码将无法工作。调度程序本身需要作为一个单例进行管理,一旦创建了对它的引用,就需要在调度程序需要启动和运行的时间内进行维护。否则,它将被垃圾收集。

    这里有一些 posts I wrote 如果你决定实施就业工厂,这可能会引起你的兴趣。