1

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

在此处输入图像描述

查看 JobBase:

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

    protected abstract void Execute();
}

还有Test.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 为 null 我的 FileName 为 null。如何使用以下用法设置属性:

  NameValueCollection properties = new NameValueCollection();
        properties["FileName"] = @"C:\temp\pingresult.txt";
        properties["Ip"] = "192.168.16.14";


        schedfabrikayeni = new StdSchedulerFactory(properties);
4

3 回答 3

1

我必须同意@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);
        }
    }
于 2012-08-07T23:11:18.960 回答
0

你从哪里得到这样的想法?我没有看到任何这样的例子。

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

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

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

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

JobDataMap 似乎正是为此目的而设计的。如果出于某种原因它对您不起作用,您最好解释它为什么不起作用。

于 2012-08-06T18:16:54.093 回答
0

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

FWIW,您拥有的代码将无法正常工作。调度程序本身需要作为单例进行管理,并且一旦创建,只要调度程序需要启动并运行,就需要维护对它的引用。否则它将被垃圾收集。

以下是我写的一些帖子,如果您决定实施工作工厂,您可能会感兴趣。

于 2012-08-07T23:02:14.183 回答