Quartz.net简单示例

12

我正在尝试寻找一个简单的Quartz.Net示例,其中当单击一个按钮时,它会启动Quartz.Net功能。

我能够使用Quartz.Net示例(控制台应用程序)并更改一些内容来生成这个(SimpleExample.cs):

    public virtual void Run()
    {
        ISchedulerFactory sf = new StdSchedulerFactory();
        IScheduler sched = sf.GetScheduler();

        DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTime.UtcNow);
        DateTimeOffset startTime = DateBuilder.NextGivenSecondDate(null, 10);

        IJobDetail job = JobBuilder.Create<HelloJob>()
            .WithIdentity("job1", "group1")
            .Build();
        ITrigger trigger = TriggerBuilder.Create()
            .WithIdentity("trigger1", "group1")
            .StartAt(runTime)
            .WithCronSchedule("5 0/1 * * * ?")
            .Build();

        sched.ScheduleJob(job, trigger);

        sched.Start();

    }

但是我对如何在按钮点击时触发此操作有些困惑。我以为可以这样做:

    private void button1_Click(object sender, EventArgs e)
    {
     code here....
    }
但是那并没有起作用。
我查阅了以下网站,但并不是所有网站都能帮助我从一个按钮点击开始。
- http://www.mkyong.com/java/quartz-scheduler-example/ - 这个是Java的,对于我来说理解起来很困难(我对这一切都很新)。
- http://www.hardcodet.net/2010/01/lightweight-task-slash-job-scheduling-with-silverlight-support - 这篇文章还是有些帮助的,但我不清楚Silverlight如何与常规的.Net表单一起使用。似乎是一个完全不同的项目。
/////
附加更改:10/14/2011
我查看了建议的代码,并在另一个(简单的)示例链接中找到了以下链接。 http://simplequartzschedulerincsharp.blogspot.com/ 然后我继续构建了一个简单的表单,并对作者的代码进行了一些修改:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Quartz;
using Quartz.Impl;

//http://simplequartzschedulerincsharp.blogspot.com/

namespace QuartzExampleWF
{
    public partial class Form1 : Form
    {
        private static IScheduler _scheduler;

        public Form1()
        {
            InitializeComponent();

            ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
            _scheduler = schedulerFactory.GetScheduler();

            AddJob();
        }
        public static void AddJob()
        {
            IMyJob myJob = new MyJob();
            JobDetail jobDetail = new JobDetail("Job1", "Group1", myJob.GetType());
            CronTrigger trigger = new CronTrigger("Trigger1", "Group1", "5 0/1 * * * ?");
            _scheduler.ScheduleJob(jobDetail, trigger);
            DateTime? nextFireTime = trigger.GetNextFireTimeUtc();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            _scheduler.Start();

        }

        internal class MyJob : IMyJob
        {
            public void Execute(JobExecutionContext context)
            {
                DateTime now = DateTime.Now;

                DoMoreWork();
            }

            public void DoMoreWork()
            {
                //more code...
            }
        }
        internal interface IMyJob : IJob
        {
        }    
    }
 }

我以前从未使用过内部类,并遇到了在其中引用文本框的问题。例如,我正在尝试执行以下操作:

      public void Execute(JobExecutionContext context)
        {
            DateTime now = DateTime.Now;
            this.textbox1 = Now.value;
            DoMoreWork();
        }

但我无法引用文本框。对于数据网格或toolStripStatusLabel也会遇到同样的问题。在上述代码下,访问类似文本框或toolStripStatusLabel的对象的最佳方法是什么?


sched需要是在click事件中可用的变量。按照您编写run方法的方式,调度程序将在run方法完成后不可用。 - jvilalta
1
刚刚发现非常有用的 Quartz.NET 教程: http://quartznet.sourceforge.net/tutorial/lesson_1.html - hfrmobile
1
很遗憾,那些例子已经过时了。上一个版本的所有类都不能与网站上的新版本一起使用。 - radu florescu
这个回答是否解决了你的问题?Quartz.net简单可行的示例 - Timothy G.
1个回答

13

你可以像这样做:

public partial class MainForm : Form
{
    IScheduler sched;
    IJobDetail job;

    public MainForm()
    {
        InitializeComponent();

        ISchedulerFactory sf = new StdSchedulerFactory();
        IScheduler sched = sf.GetScheduler();

        DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTime.UtcNow);
        DateTimeOffset startTime = DateBuilder.NextGivenSecondDate(null, 10);

        job = JobBuilder.Create<HelloJob>()
            .WithIdentity("job1", "group1")
            .Build();
        ITrigger trigger = TriggerBuilder.Create()
            .WithIdentity("trigger1", "group1")
            .StartAt(runTime)
            .WithCronSchedule("5 0/1 * * * ?")
            .Build();

        sched.ScheduleJob(job, trigger);
    }

    private void startScheduler_Click(object sender, EventArgs e)
    {
        sched.Start();
    }

    private void startJob_Click(object sender, EventArgs e)
    {
        sched.TriggerJob(job.Name, job.Group);
    }
}

对我来说不太清楚您是想要按钮启动调度器还是启动作业,因此我为两者都添加了一个按钮。关键在于您想要单独初始化调度器而不是通过按钮点击启动它。最简单的初始化位置应该是在窗体构造函数中。


1
感谢分享这段代码。startTime 没有被使用吗?Quartz.NET 2.0.1:_scheduler.TriggerJob(_jobDetail.Key); - hfrmobile
@hfrmobile 开始时间用于确定最早触发的时间。例如,现在是2013年12月16日。如果您每天都有一个9点的计划安排,但您将开始时间设置为2014年1月1日,则第一次触发不会在2014年1月1日之前发生,即使触发器已启用并且作业已计划。 - saluce
当我尝试这样做时,如果我再次点击按钮,我会得到一个Quartz.JobPersistenceException,如果我检查调度程序中的Job是否存在,则会显示不存在。 TriggerJob是否以某种方式从IScheduler中删除作业? - njkremer
1
算了,我找到答案了。我的“Job”不再被调度。我没有注意到“Job Durability”的部分。“Durability - 如果一个 job 是 non-durable 的,一旦它没有与之相关的 active triggers,就会自动从调度程序中删除。换句话说,non-durable jobs 的寿命取决于其触发器的存在。”来自 http://quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-03 - njkremer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接