12

I'm trying to find a simple Quartz.Net example where when a button is clicked, it kicks off the Quartz.Net functionality.

I was able to take the Quartz.Net example (console application) and change some things to produce this (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();

    }

But I'm a little confused as to how one triggers this from a button click. I thought I could do something like this:

    private void button1_Click(object sender, EventArgs e)
    {
     code here....
    }

But that didn't work.

I reviewed the following websites, but not all were helpful in relation to starting this from a button click.

http://www.mkyong.com/java/quartz-scheduler-example/ - Java, so hard for me to understand the difference (I'm new to all this!).

http://www.hardcodet.net/2010/01/lightweight-task-slash-job-scheduling-with-silverlight-support - This was helpful, but it is unclear to me how Silverlight works with a regular .Net Form. Seems like an entirely different project.

/////

Additional changes: 10/14/2011

I reviewed the suggested code and found the following link with another (simple) example. http://simplequartzschedulerincsharp.blogspot.com/

I went ahead and built out a simple form with a few changes to the author's code as follows:

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
        {
        }    
    }
 }

Ive never done a internal class before and ran into the issue of referencing a textbox within. For example, I am trying to do the following:

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

But I cannot reference a textbox. I would have the same issue with a datagrid or a toolStripStatusLabel. What is the best way to access objects like a textbox or a toolStripStatusLabel under the above code?

NickG
  • 9,315
  • 16
  • 75
  • 115
JAS
  • 305
  • 3
  • 5
  • 12
  • sched needs to be a variable that is available within the click event. The way you have your run method coded, the scheduler will be unavailable as soon as the run method finishes. – jvilalta Oct 13 '11 at 14:57
  • 1
    Just found very useful **Quartz.NET** lessons: http://quartznet.sourceforge.net/tutorial/lesson_1.html – hfrmobile Sep 04 '12 at 12:54
  • 1
    too bad that those example are obsolete. None of the classes from last version work with the new one from site. – radu florescu Aug 08 '13 at 11:55
  • Does this answer your question? [Simple, working example of Quartz.net](https://stackoverflow.com/questions/8821535/simple-working-example-of-quartz-net) – Timothy G. Dec 21 '21 at 04:27

1 Answers1

13

You could do something like this:

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);
    }
}

It wasn't clear to me if you wanted the button to start the scheduler or start the job, so I added a button for both. The key is that you want to initialize the scheduler separately from starting it with the button click. The simplest place to initialize it would be in the constructor for the form.

Jason Smale
  • 486
  • 1
  • 3
  • 9
  • 1
    Thanks for sharing this code. startTime is never used? Quartz.NET 2.0.1: _scheduler.TriggerJob(_jobDetail.Key); – hfrmobile Sep 04 '12 at 12:16
  • @hfrmobile The start time is used to determine when the earliest firing can be. For example, it is Dec 16, 2013. If you have a schedule for every day at 9am, but you set the start time for Jan 1, 2014, then the first firing will not happen until Jan 1, even though the trigger is enabled and the job is scheduled. – saluce Dec 16 '13 at 18:23
  • When I tried doing this, if I click the button again, I get a `Quartz.JobPersistenceException` and if I check if the `Job` exists in the scheduler it says it does not. Does `TriggerJob` somehow remove the job form the `IScheduler`? – njkremer Mar 11 '14 at 18:19
  • 1
    Nevermind, I found the answer. My `Job` was no longer scheduled. I didn't read the bit on `Job` `Durability`. "Durability - if a job is non-durable, it is automatically deleted from the scheduler once there are no longer any active triggers associated with it. In other words, non-durable jobs have a life span bounded by the existence of its triggers." from http://quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-03 – njkremer Mar 11 '14 at 18:42