Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Create gh-pages branch via GitHub

  • Loading branch information...
commit baf4880f450612e7bd90c2ffff08cf1004c6e62e 1 parent ba188cc
@lahma lahma authored
Showing with 2,733 additions and 0 deletions.
  1. +22 −0 .gitattributes
  2. +2 −0  .gitignore
  3. +1 −0  CNAME
  4. +304 −0 FAQ.md
  5. +2 −0  Gemfile
  6. +22 −0 _config.yml
  7. +168 −0 _layouts/default.html
  8. +11 −0 _layouts/redirect.html
  9. +17 −0 download.md
  10. +54 −0 features.md
  11. +14 −0 index.md
  12. +11 −0 license.md
  13. +35 −0 mailing-list.md
  14. +5 −0 mailing_list.md
  15. +111 −0 migration-guide.md
  16. +232 −0 stylesheets/default.css
  17. +33 −0 stylesheets/pygments.css
  18. +611 −0 stylesheets/site.css
  19. +23 −0 tutorial/advanced-enterprise-features.md
  20. +68 −0 tutorial/configuration-resource-usage-and-scheduler-factory.md
  21. +99 −0 tutorial/crontriggers.md
  22. +22 −0 tutorial/index.md
  23. +118 −0 tutorial/job-stores.md
  24. +66 −0 tutorial/jobs-and-triggers.md
  25. +5 −0 tutorial/lesson_1.md
  26. +5 −0 tutorial/lesson_10.md
  27. +5 −0 tutorial/lesson_11.md
  28. +5 −0 tutorial/lesson_12.md
  29. +5 −0 tutorial/lesson_2.md
  30. +5 −0 tutorial/lesson_3.md
  31. +5 −0 tutorial/lesson_4.md
  32. +5 −0 tutorial/lesson_5.md
  33. +5 −0 tutorial/lesson_6.md
  34. +5 −0 tutorial/lesson_7.md
  35. +5 −0 tutorial/lesson_8.md
  36. +5 −0 tutorial/lesson_9.md
  37. +31 −0 tutorial/miscellaneous-features.md
  38. +183 −0 tutorial/more-about-jobs.md
  39. +141 −0 tutorial/more-about-triggers.md
  40. +41 −0 tutorial/scheduler-listeners.md
  41. +118 −0 tutorial/simpletriggers.md
  42. +70 −0 tutorial/trigger-and-job-listeners.md
  43. +38 −0 tutorial/using-quartz.md
View
22 .gitattributes
@@ -0,0 +1,22 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+*.sln merge=union
+*.csproj merge=union
+*.vbproj merge=union
+*.fsproj merge=union
+*.dbproj merge=union
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
View
2  .gitignore
@@ -0,0 +1,2 @@
+/_site
+/*.lock
View
1  CNAME
@@ -0,0 +1 @@
+www.quartz-scheduler.net
View
304 FAQ.md
@@ -0,0 +1,304 @@
+---
+layout: default
+title: Frequently Asked Questions
+---
+
+*This FAQ was adapted from Quartz Java*
+
+# General Questions
+
+## What is Quartz
+
+Quartz is a job scheduling system that can be integrated with, or used along
+side virtually any other software system. The term "job scheduler" seems to
+conjure different ideas for different people. As you read this tutorial, you
+should be able to get a firm idea of what we mean when we use this term, but
+in short, a job scheduler is a system that is responsible for executing
+(or notifying) other software components when a pre-determined (scheduled)
+time arrives.
+
+Quartz is quite flexible, and contains multiple usage paradigms that can be
+used separately or together, in order to achieve your desired behavior, and
+enable you to write your code in the manner that seems most 'natural' to
+your project.
+
+Quartz is very light-weight, and requires very little setup/configuration -
+it can actually be used 'out-of-the-box' if your needs are relatively basic.
+
+Quartz is fault-tolerant, and can persist ('remember') your scheduled
+jobs between system restarts.
+
+Although Quartz is extremely useful for simply running certain system
+processes on given schedules, the full potential of Quartz can be realized
+when you learn how to use it to drive the flow of your application's
+business processes.
+
+## What is Quartz - From a Software Component View?
+
+Quartz is distributed as a small dynamically linked library (.dll file)
+that contains all of the core Quartz functionality. The main interface (API) to this
+functionality is the Scheduler interface. It provides simple operations
+such as scheduling/unscheduling jobs, starting/stopping/pausing the scheduler.
+
+If you wish to schedule your own software components for execution they must
+implement the simple Job interface, which contains the method execute().
+If you wish to have components notified when a scheduled fire-time arrives,
+then the components should implement either the TriggerListener or JobListener
+interface.
+
+The main Quartz 'process' can be started and ran within your own application,
+or a stand-alone application (with an remote interface).
+
+# Why not just use System.Timers.Timer?
+
+.NET Framework has "built-in" timer capabilities, through the
+System.Timers.Timer class - why would someone use Quartz rather than these
+standard features?
+
+There are many reasons! Here are a few:
+
+* Timers have no persistence mechanism.
+* Timers have inflexible scheduling (only able to set start-time & repeat interval, nothing based on dates, time of day, etc.
+* Timers don't utilize a thread-pool (one thread per timer)
+* Timers have no real management schemes - you'd have to write your own mechanism for being able to remember, organize and retreive your tasks by name, etc.
+
+...of course to some simple applications these features may not be important,
+in which case it may then be the right decision not to use Quartz.NET.
+
+## How do I build the Quartz source?
+
+Although Quartz ships "pre-built" many people like to make their own
+alterations and/or build the latest 'non-released' version of Quartz from
+Subversion. To do this, follow the instructions in the "README.TXT" file
+that ships with Quartz.
+
+# Miscellaneous Questions</title>
+
+## How many jobs is Quartz capable of running?
+
+This is a tough question to answer... the answer is basically "it depends".
+
+I know you hate that answer, to here's some information about what it depends "on".
+
+First off, the JobStore that you use plays a significant factor.
+The RAM-based JobStore is MUCH (1000x) faster than the ADO.NET-based JobStore.
+The speed of AdoJobStore depends almost entirely on the speed of the
+connection to your database, which data base system that you use, and what
+hardware the database is running on. Quartz actually does very little
+processing itself, nearly all of the time is spent in the database. Of course
+RAMJobStore has a more finite limit on how many Jobs & Triggers can be stored,
+as you're sure to have less RAM than hard-drive space for a database.
+You may also look at the FAQ "How do I improve the performance of AdoJobStore?"
+
+So, the limitting factor of the number of Triggers and Jobs Quartz can "store"
+and monitor is really the amount of storage space available to the JobStore
+(either the amount of RAM or the amount of disk space).
+
+Now, aside from "how many can I store?" is the question of "how many jobs
+can Quartz be running at the same moment in time?"
+
+One thing that CAN slow down quartz itself is using a lot of listeners
+(TriggerListeners, JobListeners, and SchedulerListeners). The time spent in
+each listener obviously adds into the time spent "processing" a job's
+execution, outside of actual execution of the job. This doesn't mean that
+you should be terrified of using listeners, it just means that you should
+use them judiciously - don't create a bunch of "global" listeners if you can
+really make more specialized ones. Also don't do "expensive" things in the
+listeners, unless you really need to. Also be mindful that many
+plug-ins (such as the "history" plugin) are actually listeners.
+
+The actual number of jobs that can be running at any moment in time is
+limitted by the size of the thread pool. If there are five threads in
+the pool, no more than five jobs can run at a time. Be careful of making a
+lot of threads though, as the VM, Operating System, and CPU all have a hard
+time juggling lots of threads, and performance degrades just because of all
+of the management. In most cases performance starts to tank as you get into
+the hundreds of threads. Be mindful that if you're running within an
+application server, it probably has created at least a few dozen threads
+of its own!
+
+Aside from those factors, it really comes down to what your jobs DO.
+If your jobs take a long time to complete their work, and/or their work is
+very CPU-intensive, then you're obviously not going to be able to run very
+many jobs at once, nor very many in a given spanse of time.
+
+Finally, if you just can't get enough horse-power out of one Quartz instance,
+you can always load-balance many Quartz instances (on separate machines).
+Each will run the jobs out of the shared database on a first-come first-serve
+basis, as quickly as the triggers need fired.
+
+So here you are this far into the answer of "how many", and I still
+haven't given you a number And I really hate to, because of all of the
+variables mentioned above. So let me just say, there are installments of
+Quartz Java out there that are managing hundreds-of-thousands of Jobs and Triggers,
+and that at any given moment in time are executing dozens of jobs - and this
+excludes using load-balancing. With this in mind, most people should feel
+confident that they can get the performance out of Quartz that they need.
+
+# Questions About Jobs
+
+## How can I control the instantiation of Jobs?</title>
+
+See Quartz.Spi.IJobFactory and the Quartz.IScheduler.JobFactory property.
+
+## How do I keep a Job from being removed after it completes?</title>
+
+Set the property JobDetail.Durable = true - which instructs Quartz not to
+delete the Job when it becomes an "orphan" (when the Job not longer has a
+Trigger referencing it).
+
+## How do I keep a Job from firing concurrently?
+
+Make the job class implement IStatefulJob rather than Job. Read the API
+documentation for IStatefulJob for more information.
+
+## How do I stop a Job that is currently executing?
+
+See the Quartz.IInterruptableJob interface, and the
+Scheduler.Interrupt(string, string) method.
+
+# Questions About Triggers
+
+## How do I chain Job execution? Or, how do I create a workflow?
+
+There currently is no "direct" or "free" way to chain triggers with Quartz.
+However there are several ways you can accomplish it without much effort.
+Below is an outline of a couple approaches:
+
+One way is to use a listener (i.e. a TriggerListener, JobListener or
+SchedulerListener) that can notice the completion of a job/trigger and then
+immediately schedule a new trigger to fire. This approach can get a bit
+involved, since you'll have to inform the listener which job follows which
+- and you may need to worry about persistence of this information.
+
+Another way is to build a Job that contains within its JobDataMap the name
+of the next job to fire, and as the job completes (the last step in its
+Execute() method) have the job schedule the next job. Several people are
+doing this and have had good luck. Most have made a base (abstract) class
+that is a Job that knows how to get the job name and group out of the
+JobDataMap using special keys (constants) and contains code to schedule the
+identified job. Then they simply make extensions of this class that included
+the additional work the job should do.
+
+In the future, Quartz will provide a much cleaner way to do this, but until
+then, you'll have to use one of the above approaches, or think of yet another
+that works better for you.
+
+
+## Why isn't my trigger firing?
+
+The most common reason for this is not having called Scheduler.Start(),
+which tells the scheduler to start firing triggers.
+
+The second most common reason is that the trigger or trigger group
+has been paused.
+
+## Daylight Saving Time and Triggers
+
+
+CronTrigger and SimpleTrigger each handle daylight savings time in their own
+way - each in the way that is intuitive to the trigger type.
+
+
+
+First, as a review of what daylight savings time is, please read this resource:
+http://webexhibits.org/daylightsaving/g.html . Some readers may be unaware
+that the rules are different for different nations/contents. For example,
+the 2005 daylight savings time starts in the United States on April 3, but
+in Egypt on April 29. It is also important to know that not only the dates
+are different for different locals, but the time of the shift is different
+as well. Many places shift at 2:00 am, but others shift time at 1:00 am,
+others at 3:00 am, and still others right at midnight.
+
+
+
+SimpleTrigger allows you to schedule jobs to fire every N milliseconds.
+As such, it has to do nothing in particular with respect to daylight
+savings time in order to "stay on schedule" - it simply keeps firing every
+N milliseconds. Regardless your SimpleTrigger is firing every 10 seconds,
+or every 15 minutes, or every hour or every 24 hours it will continue to do
+so. However the implication of this which confuses some users is that if
+your SimpleTrigger is firing say every 12 hours, before daylight savings
+switches it may be firing at what appears to be 3:00 am and 3:00 pm,
+but after daylight savings 4:00 am and 4:00 pm. This is not a bug
+- the trigger has kept firing exacly every N milliseconds, it just that the
+"name" of that time that humans impose on that moment has changed.
+
+
+
+CronTrigger allows you to schedule jobs to fire at certain moments with
+respect to a "gregorian calendar". Hence, if you create a trigger to fire
+every day at 10:00 am, before and after daylight savings time switches it
+will continue to do so. However, depending on whether it was the Spring or
+Autumn daylight savings event, for that particular Sunday, the actual time
+interval between the firing of the trigger on Sundary morning at 10:00 am
+since its firing on Saturday morning at 10:00 am will not be 24 hours,
+but will instead be 23 or 25 hours respectively.
+
+
+
+There is one additional point users must understand about CronTrigger with
+respect to daylight savings. This is that you should take careful thought
+about creating schedules that fire between midnight and 3:00 am (the critical
+window of time depends on your trigger's locale, as explained above).
+The reason is that depending on your trigger's schedule, and the particular
+daylight event, the trigger may be skipped or may appear to not fire for an
+hour or two. As examples, say you are in the United States, where daylight
+savings events occur at 2:00 am. If you have a CronTrrigger that fires every
+day at 2:15 am, then on the day of the beginning of daylight savings time
+the trigger will be skipped, since, 2:15 am never occurs that day. If you
+have a CronTrigger that fires every 15 minutes of every hour of every day,
+then on the day daylight savings time ends you will have an hour of time
+for which no triggerings occur, because when 2:00 am arrives, it will become
+1:00 am again, however all of the firings during the one o'clock hour have
+already occurred, and the trigger's next fire time was set to 2:00 am
+- hence for the next hour no triggerings will occur.
+
+
+
+In summary, all of this makes perfect sense, and should be easy to remember
+if you keep these two rules in mind:
+
+* SimpleTrigger ALWAYS fires exacly every N seconds, with no relation to the time of day.
+* CronTrigger ALWAYS fires at a given time of day and then computes its next time to fire. If that time does not occur on a given day, the trigger will be skipped. If the time occurs twice in a given day, it only fires once, because after firing on that time the first time, it computes the next time of day to fire on.
+
+# Questions About AdoJobStore
+
+## How do I improve the performance of AdoJobStore?
+
+There are a few known ways to speed up AdoJobStore, only one of which is
+very practical.
+
+First, the obvious, but not-so-practical:
+
+* Buy a better (faster) network between the machine that runs Quartz, and the machine that runs your RDBMS.
+* Buy a better (more powerful) machine to run your database on.
+* Buy a better RDBMS.
+
+Use driver delegate implementation that is specific to your database, like SQLServerDelegate, for best performance.
+
+Now for something simple, but effective: Build indexes on the Quartz tables.
+
+Most database systems will automatically put indexes on the primary-key
+fields, many will also automatically do it for the foreign-key field.
+Make sure yours does this, or make the indexes on all key fields
+of every table manually.
+
+Next, manually add some additional indexes: most important to index are
+the TRIGGER table's "next_fire_time" and "state" fields. Last
+(but not as important), add indexes to every column on the FIRED_TRIGGERS table.
+
+**Create Table Indexes**
+
+```sql
+create index idx_qrtz_t_next_fire_time on qrtz_triggers(NEXT_FIRE_TIME);
+create index idx_qrtz_t_state on qrtz_triggers(TRIGGER_STATE);
+create index idx_qrtz_t_nf_st on qrtz_triggers(TRIGGER_STATE,NEXT_FIRE_TIME);
+create index idx_qrtz_ft_trig_name on qrtz_fired_triggers(TRIGGER_NAME);
+create index idx_qrtz_ft_trig_group on qrtz_fired_triggers(TRIGGER_GROUP);
+create index idx_qrtz_ft_trig_name on qrtz_fired_triggers(TRIGGER_NAME);
+create index idx_qrtz_ft_trig_n_g on qrtz_fired_triggers(TRIGGER_NAME,TRIGGER_GROUP);
+create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(INSTANCE_NAME);
+create index idx_qrtz_ft_job_name on qrtz_fired_triggers(JOB_NAME);
+create index idx_qrtz_ft_job_group on qrtz_fired_triggers(JOB_GROUP);
+```
View
2  Gemfile
@@ -0,0 +1,2 @@
+source 'https://rubygems.org'
+gem 'github-pages'
View
22 _config.yml
@@ -0,0 +1,22 @@
+# Name of your blog (this will show up at the top of your page and in the RSS feed)
+name: Quartz.NET Documentation
+
+# Short description (goes below the title; it will also be used in the RSS feed)
+description:
+
+# Your name, as you want it to appear underneath each post and in the footer
+author: Marko Lahma
+
+category_dir: /
+baseurl:
+
+url: http://www.quartz-scheduler.net/
+
+#### Under the Hood Stuff #####
+
+markdown: redcarpet
+pygments: true
+
+exclude: [README.markdown, package.json, grunt.js, Gruntfile.js, node_modules, Gemfile, Gemfile.lock]
+
+encoding: UTF-8
View
168 _layouts/default.html
@@ -0,0 +1,168 @@
+<!DOCTYPE html>
+
+<html>
+
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+ <meta name="description" content="Quartz.NET is a port of Java Quartz which is an enterprise class job sheduling system. Quartz.NET is a free open source tool that you can use in your .NET applications.">
+ <meta name="keywords" content="Quartz.NET Quartz Scheduler Scheduling .NET C# cron timer free download open source">
+ <meta name="description" content="{{site.description}}"/>
+ <meta name="author" content="{{site.author}}"/>
+ <link href="{{site.baseurl}}/stylesheets/default.css" rel="stylesheet" />
+ <link href="{{site.baseurl}}/stylesheets/pygments.css" rel="stylesheet" />
+ <title>{% if page.title %} {{ page.title }} | {% endif %} {{ site.name }}</title>
+ </head>
+
+ <body>
+
+ <div class="container">
+
+ <div class="header">
+
+ <div class="title">
+ <h1>Quartz.NET - {{ page.title }}
+ </h1>
+ </div>
+ </div>
+
+ <div class="main">
+
+ <div class="content">
+
+ <article id="MainDiv">
+ <div id="MainHeaderDiv">
+ </div>
+ <div id="PageInternalHeaderDiv">
+ </div>
+ <a id="PageTop"></a>
+ <div id="PageHeaderDiv">
+ <h1 class="pagetitle">{{ page.title }}</h1>
+ </div>
+ <div id="PageContentDiv">
+ {{ content }}
+ </div>
+ </article>
+
+ </div>
+
+ <div class="sidenav">
+
+ <h1>Search</h1>
+ <!-- SiteSearch Google -->
+
+ <form method="get" action="http://www.google.com/custom" target="_top">
+ <table border="0" bgcolor="#ffffff">
+ <tr>
+ <td nowrap="nowrap" valign="top" align="left" height="32"></td>
+ <td nowrap="nowrap">
+ <input type="hidden" name="domains" value="quartznet.sourceforge.net"></input>
+ <label for="sbi" style="display: none">Enter your search terms</label>
+ <input type="text" name="q" size="31" maxlength="255" value="" id="sbi"></input>
+ <label for="sbb" style="display: none">Submit search form</label>
+ <input type="submit" name="sa" value="Google Search" id="sbb"></input>
+ </td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td nowrap="nowrap">
+ <table>
+ <tr>
+ <td>
+ <input type="radio" name="sitesearch" value="" checked id="ss0"></input>
+ <label for="ss0" title="Search the Web"><font size="-1" color="#000000">Web</font>
+ </label>
+ </td>
+ <td>
+ <input type="radio" name="sitesearch" value="quartznet.sourceforge.net" id="ss1"></input>
+ <label for="ss1" title="Search quartznet.sourceforge.net"><font size="-1" color="#000000">quartznet.sourceforge.net</font>
+ </label>
+ </td>
+ </tr>
+ </table>
+ <input type="hidden" name="client" value="pub-2642923360660292"></input>
+ <input type="hidden" name="forid" value="1"></input>
+ <input type="hidden" name="ie" value="ISO-8859-1"></input>
+ <input type="hidden" name="oe" value="ISO-8859-1"></input>
+ <input type="hidden" name="safe" value="active"></input>
+ <input type="hidden" name="cof" value="GALT:#008000;GL:1;DIV:#336699;VLC:663399;AH:center;BGC:FFFFFF;LBGC:336699;ALC:0000FF;LC:0000FF;T:000000;GFNT:0000FF;GIMP:0000FF;FORID:1"></input>
+ <input type="hidden" name="hl" value="en"></input>
+ </td>
+ </tr>
+ </table>
+ </form>
+ <!-- SiteSearch Google -->
+
+ <h1>Quartz.NET</h1>
+ <ul>
+ <li><a href="{{site.baseurl}}/index.html">Home</a></li>
+ <li><a href="{{site.baseurl}}/features.html">Features</a></li>
+ <li><a href="{{site.baseurl}}/download.html">Download</a></li>
+ <li><a href="{{site.baseurl}}/license.html">License</a></li>
+ <li><a href="{{site.baseurl}}/tutorial/index.html">Tutorial</a></li>
+ <li><a href="{{site.baseurl}}/faq.html">FAQ</a></li>
+ <li><a href="{{site.baseurl}}/apidoc/2.0/html/webframe.html">API Documentation (2.x)</a>
+ </li>
+ <li><a href="{{site.baseurl}}/apidoc/1.0/html/index.html">API Documentation (1.0)</a>
+ </li>
+ <li><a href="{{site.baseurl}}/mailing-list.html">Mailing List</a></li>
+ </ul>
+ <p>
+ <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
+ <input type="hidden" name="cmd" value="_s-xclick">
+ <input type="hidden" name="hosted_button_id" value="35W4FP7HXVUB4"><input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
+ <img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
+ </form>
+ </p>
+
+ <h1>Related</h1>
+ <ul>
+ <li><a href="https://github.com/quartznet/">GitHub Project (source)</a></li>
+ <li><a href="http://sourceforge.net/projects/quartznet">Source Forge Project (downloads)</a>
+ </li>
+ <li><a href="http://www.quartz-scheduler.org/">Quartz (Java)</a></li>
+ </ul>
+
+ <h1>Project Supporters</h1>
+ <p align="center">
+ <a href="http://www.innovasys.com">
+ Supported by Innovasys (Document! X)
+ <br />
+ <br />
+ <a href="http://sourceforge.net">
+ <img src="http://sflogo.sourceforge.net/sflogo.php?group_id=174134&amp;type=1" width="88"
+ height="31" border="0" alt="SourceForge.net Logo" /></a>
+ </p>
+
+ <p>
+
+ <script type="text/javascript">
+ google_ad_client = "pub-2642923360660292";
+ /* 160x600, created 2/6/08 */
+ google_ad_slot = "5222703235";
+ google_ad_width = 160;
+ google_ad_height = 600;
+ </script>
+ <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
+
+ </p>
+
+ </div>
+
+ <div class="clearer"><span></span></div>
+
+ </div>
+ </div>
+
+
+ <div class="footer">
+ Template design by <a href="http://arcsin.se">Arcsin</a>
+ </div>
+ <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.min.js"> </script>
+ <script src="http://www.google-analytics.com/urchin.js" type="text/javascript"> </script>
+ <script type="text/javascript">
+ _uacct = "UA-1433901-1";
+ // urchinTracker();
+ </script>
+ </body>
+
+</html>
View
11 _layouts/redirect.html
@@ -0,0 +1,11 @@
+<html>
+
+ <head>
+ <meta http-equiv="refresh" content="0; url={{site.url}}{{page.redirect}}">
+ <link rel="canonical" href="{{site.url}}{{page.redirect}}" />
+ </head>
+
+ <body>
+ </body>
+
+</html>
View
17 download.md
@@ -0,0 +1,17 @@
+---
+title: Download Quartz.NET
+layout: default
+---
+
+# Download
+
+Latest stable version of Quartz.NET is 2.2.1
+
+Either grab it from NuGet
+
+```
+Install-Package Quartz
+```
+
+
+or [Source Forge downloads](http://sourceforge.net/projects/quartznet/files/quartznet/).
View
54 features.md
@@ -0,0 +1,54 @@
+---
+title: Quartz.NET Features
+layout: default
+---
+
+# Quartz.NET Features
+
+## Runtime Environments
+
+* Quartz.NET can run embedded within another free standing application
+* Quartz.NET can run as a stand-alone program (within its own .NET virtual machine instance), to be used via .NET Remoting
+* Quartz.NET can be instantiated as a cluster of stand-alone programs (with load-balance and fail-over capabilities)
+
+## Job Scheduling
+
+Jobs are scheduled to run when a given Trigger occurs. Triggers can be created with nearly any combination of the following directives:
+
+* at a certain time of day (to the millisecond)
+* on certain days of the week
+* on certain days of the month
+* on certain days of the year
+* not on certain days listed within a registered Calendar (such as business holidays)
+* repeated a specific number of times
+* repeated until a specific time/date
+* repeated indefinitely
+* repeated with a delay interval
+
+Jobs are given names by their creator and can also be organized into named groups.
+Triggers may also be given names and placed into groups, in order to easily organize them within the scheduler.
+Jobs can be added to the scheduler once, but registered with multiple Triggers.
+
+## Job Execution
+
+* Jobs can be any .NET class that implements the simple IJob interface, leaving infinite possibilities for the work Jobs can perform.
+* Job class instances can be instantiated by Quartz.NET, or by your application's framework.
+* When a Trigger occurs, the scheduler notifies zero or more .NET objects implementing the JobListener and TriggerListener interfaces. These listeners are also notified after the Job has executed.
+* As Jobs are completed, they return a JobCompletionCode which informs the scheduler of success or failure. The JobCompletionCode can also instruct the scheduler of any actions it should take based on the success/fail code - such as immediate re-execution of the Job.
+
+## Job Persistence
+
+* The design of Quartz.NET includes a IJobStore interface that can be implemented to provide various mechanisms for the storage of jobs.
+* With the use of the included AdoJobStore, all Jobs and Triggers configured as "non-volatile" are stored in a relational database via ADO.NET.
+* With the use of the included RAMJobStore, all Jobs and Triggers are stored in RAM and therefore do not persist between program executions - but this has the advantage of not requiring an external database.
+
+## Clustering
+
+* Fail-over.
+* Load balancing.
+
+## Listeners & Plug-Ins
+
+* Applications can catch scheduling events to monitor or control job/trigger behavior by implementing one or more listener interfaces.
+* The Plug-In mechanism can be used add functionality to Quartz, such keeping a history of job executions, or loading job and trigger definitions from a file.
+* Quartz ships with a number of "factory built" plug-ins and listeners.
View
14 index.md
@@ -0,0 +1,14 @@
+---
+title: Quartz Enterprise Scheduler .NET
+layout: default
+---
+
+
+# Welcome to the home of Quartz.NET!
+
+<cite>
+Quartz.NET is a full-featured, open source job scheduling system that can be used from smallest apps to large scale enterprise systems.
+</cite>
+
+Quartz.NET is a pure .NET library written in C# and is a port of very popular open source Java job scheduling framework, <a href="http://www.quartz-scheduler.org">Quartz</a>. This project owes very much to original Java project, it's father James House and the project contributors.
+
View
11 license.md
@@ -0,0 +1,11 @@
+---
+title: License
+layout: default
+---
+
+# License
+
+Quartz.NET is licensed under the terms of the Apache License, Version 2.0.
+
+<a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>
+(<a href="http://www.apache.org/licenses/LICENSE-2.0.txt">TXT</a> or <a href="http://www.apache.org/licenses/LICENSE-2.0.html">HTML</a>)
View
35 mailing-list.md
@@ -0,0 +1,35 @@
+---
+title: Mailing List
+layout: default
+---
+
+# Quartz.NET Mailing List
+
+Quartz.NET mailing list is currently operated on <a href="http://groups.google.com/group/quartznet">Google Groups</a>.
+
+Please send your questions and other ideas here so we share them with everybody.
+
+
+<div align="center">
+ <form action="http://groups.google.com/group/quartznet/boxsubscribe">
+ <table border="0" style="background-color: #fff; padding: 5px;" cellspacing="0">
+ <tr>
+ <td style="padding-left: 5px">
+ <b>Subscribe to Quartz.NET</b>
+ </td>
+ </tr>
+ <input type="hidden" name="hl" value="en" />
+ <tr>
+ <td style="padding-left: 5px;">
+ Email: <input type="text" name="email" />
+ <input type="submit" name="sub" value="Subscribe" />
+ </td>
+ </tr>
+ <tr>
+ <td align="right">
+ <a href="http://groups.google.com/group/quartznet?hl=en">Visit this group</a>
+ </td>
+ </tr>
+ </table>
+ </form>
+</div>
View
5 mailing_list.md
@@ -0,0 +1,5 @@
+---
+title: Mailing List
+redirect: mailing-list.html
+layout: redirect
+---
View
111 migration-guide.md
@@ -0,0 +1,111 @@
+---
+layout: default
+title: Version Migration Guide
+---
+
+# Version Migration Guide
+
+*This document outlines changes needed per version upgrade basis.*
+
+# Upgrading from 1.0 to 2.0
+
+## API Changes
+
+The most obvious differences with version 2.0 are the significant changes to the API.
+These changes have aimed to: modernize the API to use collections and generics, remove ambiguities and redundancies,
+hide/remove methods that should not be public to client code, improve separation of concerns, and introduce
+a Domain Specific Language (DSL) for working with the core entities (jobs and triggers).
+
+
+While the API changes are significant, and the usage of the "new way of doing things" is highly encouraged,
+there are some formulaic (search-and-replace) techniques that can be used to get 1.x code quickly working with version 2.0.
+See the migration guide for more information.
+
+**Outline of most significant API changes:**
+
+
+API methods that return (or take as parameters) arrays now return (or take) typed collections.
+For example, rather than GetJobGroupNames(): string[] we now have GetJobGroupNames(): IList&lt;string&gt;
+Job and Trigger identification is now based on JobKey and TriggerKey. Keys include both a name and group.
+Methods which operate on particular jobs/triggers now take keys as the parameter. For example, GetTrigger(TriggerKey key): ITrigger,
+rather than GetTrigger(string name, string group): Trigger.
+ITrigger is now an interface, rather than a class. Likewise for ISimpleTrigger, ICronTrigger, etc.
+New DSL/builder-based API for construction Jobs and Triggers:
+
+```c#
+IJobDetail job = JobBuilder.Create<SimpleJob>()
+ .WithIdentity("job1", "group1")
+ .Build();
+
+ITrigger trigger = TriggerBuilder.Create()
+ .WithIdentity("trigger1", "group1")
+ .StartAt(DateBuilder.FutureDate(2, IntervalUnit.HOURS))
+ .WithSimpleSchedule(x => x.RepeatHourlyForever())
+ .ModifiedByCalendar("holidays")
+ .Build();
+```
+
+Methods from TriggerUtils related to easy construction of Dates have been moved to new DateBuilder class,
+that can be used with static imports to nicely create Date instances for trigger start and end times, etc.
+
+
+// build a date for 9:00 am on Halloween
+DateTimeOffset runDate = DateBuilder.DateOf(0, 0, 9, 31, 10);
+// build a date 2 hours in the future
+DateTimeOffset myDate = DateBuilder.FutureDate(2, IntervalUnit.HOURS);
+
+The IStatefulJob interface has been deprecated in favor of new class-level attributes for IJob implementations
+(using both attributes produces equivalent to that of the old IStatefulJob interface):
+
+```c#
+[PersistJobDataAfterExecution]
+```
+
+Instructs the scheduler to re-store the Job's JobDataMap contents after execution completes.
+
+```c#
+[DisallowConcurrentExecution]
+```
+
+Instructs the scheduler to block other instances of the same job (by JobKey) from executing when one already is.
+
+Significant changes to usage of JobListener and TriggerListener:
+
+* Removal of distinction between "global" and "non-global" listeners
+* JobDetails and Triggers are no longer configured with a list of names of listeners to notify, instead listeners identify which jobs/triggers they're interested in.
+* Listeners are now assigned a set of Matcher instances - which provide matching rules for jobs/triggers they wish to receive events for.
+* Listeners are now managed through a ListenerManager API, rather than directly with the Scheduler API.
+
+
+
+* The SchedulerException class and class hierarchy has been cleaned up.
+* DateIntervalTrigger was renamed to CalendarIntervalTrigger (or more exactly the concrete class is now CalendarIntervalTriggerImpl).
+* The notion (property) of "volatility" of jobs and triggers has been eliminated.
+* New trigger misfire instruction MisfireInstruction.IgnoreMisfirePolicy lets a trigger be configured in such a way
+ that it is selectively ignored from all misfire handling. In other words, it will fire as soon as it can, with no special handling -
+ a great option for improving performance particularly with setups that have lots of one-shot (non-repeating) triggers.
+* Trigger's CompareTo() method now correctly relates to its Equals() method, in that it compares the trigger's key, rather than next fire time.
+A new Comparator that sorts triggers according to fire time, priority and key was added as Trigger.TriggerTimeComparator.
+
+## New Features
+
+* Scheduler.Clear() method provides convenient (and dangerous!) way to remove all jobs, triggers and calendars from the scheduler.
+* Scheduler.ScheduleJobs(IDictionary&lt;IJobDetail, IList&lt;ITrigger&gt;&gt; triggersAndJobs, boolean replace) method provides convenient bulk addition of jobs and triggers.
+* Scheduler.UnscheduleJobs(IList&lt;TriggerKey&gt; triggerKeys) method provides convenient bulk unscheduling of jobs.
+* Scheduler.DeleteJobs(IList&lt;JobKey&gt; jobKeys) method provides convenient bulk deletion of jobs (and related triggers).
+* Scheduler.CheckExists(JobKey jobKey) and Scheduler.CheckExists(TriggerKey triggerKey) methods provides convenient way to determine uniqueness of job/trigger keys (as opposed to old have of having to retrieve the job/trigger by name and then check whether the result was null).
+* AdoJobStore now allows one set of tables to be used by multiple distinct scheduler instances
+* AdoJobStore is now capable of storing non-core Trigger implementations without using BLOB columns, through the use of the new TriggerPersistenceDelegate interface, which can (optionally) be implemented by implementers of custom Trigger types.
+* Cron expressions now support the ability to specify an offset for "last day of month" and "last weekday of month" expressions. For examples: "L-3" (three days back from the last of the month) or "L-3W" (nearest weekday to the day three days back from the last day of the month).
+* XML files containing scheduling data now have a way to specify trigger start times as offsets into the future from the time the file is processed (useful for triggers that need to begin firing some time after the application is launched/deployed).
+ From schema: &lt;xs:element name="start-time-seconds-in-future" type="xs:nonNegativeInteger"/&gt;
+* XML file schema now supports specifying the 'priority' property of triggers.
+* Added DirectoryScanJob to core jobs that ship with Quartz, also added minimum age parameter to pre-existing FileScanJob.
+
+## Miscellaneous
+
+Various performance improvements, including (but not limited to):
+
+* Ability to batch-acquire triggers that are ready to be fired, which can provide performance improvements for very busy schedulers
+* Methods for batch addition/removal of jobs and triggers (see "New Features")
+* Triggers have a new misfire instruction option, MisfireInstruction.IgnoreMisfirePolicy, which may be useful if you do not require misfire handling for your trigger(s), and want to take advantage of a performance gain
View
232 stylesheets/default.css
@@ -0,0 +1,232 @@
+/*#############################################################
+Name: Indigo
+Description: A lightweight (7kb images), simple and professional design.
+Date: 2006-07-27
+Author: Viktor Persson
+URL: http://arcsin.se
+
+Feel free to use and modify but please provide credits.
+#############################################################*/
+
+/* standard elements */
+*
+{
+ margin: 0;
+ padding: 0;
+}
+a
+{
+ color: #F70;
+}
+a:hover
+{
+ color: #C60;
+}
+body
+{
+ background: #0094D6 url(img/bg.gif) repeat-x;
+ color: #466;
+ font: normal 62.5% "Lucida Sans Unicode" ,sans-serif;
+ margin: 0;
+}
+input
+{
+ color: #555;
+ font: normal 1.1em "Lucida Sans Unicode" ,sans-serif;
+}
+p, cite, code, ul
+{
+ font-size: 1.2em;
+ padding-bottom: 1.2em;
+}
+h1
+{
+ font-size: 1.4em;
+ margin-bottom: 4px;
+}
+code
+{
+ background: url(img/bgcode.gif);
+ border: 1px solid #F0F0F0;
+ border-left: 6px solid #39F;
+ color: #555;
+ display: block;
+ font: normal 1.1em "Lucida Sans Unicode" ,serif;
+ margin-bottom: 12px;
+ padding: 8px 10px;
+ white-space: pre;
+}
+cite
+{
+ background: url(img/quote.gif) no-repeat;
+ color: #666;
+ display: block;
+ font: normal 1.3em "Lucida Sans Unicode" ,serif;
+ padding-left: 28px;
+}
+h1, h2, h3
+{
+ color: #06C;
+ padding-top: 6px;
+ padding-bottom: 10px;
+}
+/* misc */
+.clearer
+{
+ clear: both;
+}
+
+/* structure */
+.container
+{
+ background: url(img/topleft.gif) no-repeat;
+}
+
+.header
+{
+ height: 92px;
+}
+
+/* title */
+.title
+{
+ float: left;
+ padding: 28px 0 0 76px;
+}
+.title h1
+{
+ color: #FFF;
+ font: normal 2em Verdana,sans-serif;
+}
+/* navigation */
+.navigation
+{
+ float: left;
+ height: 92px;
+ margin-left: 24px;
+ padding: 0 16px;
+}
+.navigation a
+{
+ color: #FFF;
+ float: left;
+ font: bold 1.2em "Trebuchet MS" ,sans-serif;
+ margin-top: 56px;
+ padding: 8px 18px;
+ text-align: center;
+ text-decoration: none;
+}
+.navigation a:hover
+{
+ background-color: #4A91C3;
+ color: #FFF;
+}
+
+/* main */
+.main
+{
+ background: #FFF url(img/bgmain.gif) no-repeat;
+ clear: both;
+ padding: 12px 12px 0 52px;
+}
+
+/* main left */
+.sidenav
+{
+ float: left;
+ width: 24%;
+}
+.sidenav h1
+{
+ border-bottom: 1px dashed #DDD;
+ color: #E73;
+ font-size: 1.2em;
+ height: 20px;
+ margin-top: 1.2em;
+}
+.sidenav ul
+{
+ margin: 0;
+ padding: 0;
+}
+.sidenav li
+{
+ border-bottom: 1px dashed #EEE;
+ list-style: none;
+ margin: 0;
+}
+.sidenav li a
+{
+ color: #777;
+ display: block;
+ font-size: 0.9em;
+ padding: 3px 6px 3px 18px;
+ text-decoration: none;
+}
+.sidenav li a:hover
+{
+ color: #111;
+ background: url(img/nav_li.gif) no-repeat;
+}
+
+/* content */
+.content
+{
+ float: left;
+ margin-right: 4%;
+ width: 69%;
+}
+.content .descr
+{
+ color: #C60;
+ margin-bottom: 6px;
+}
+.content li
+{
+ list-style: url(img/li.gif);
+ margin-left: 18px;
+}
+
+/* search form */
+.styled
+{
+ border: 3px double #E5E5E5;
+ padding: 2px 3px;
+}
+.button
+{
+ border: 1px solid #AAA;
+ margin-left: 5px;
+ padding: 2px 3px;
+}
+
+/* footer */
+.footer
+{
+ background: #0094D6 url(img/bgfooter.gif) repeat-x;
+ color: #C1DEF0;
+ font-size: 1.1em;
+ line-height: 40px;
+ text-align: center;
+}
+.footer a
+{
+ color: #FFF;
+ text-decoration: none;
+}
+.footer a:hover
+{
+ color: #FFF;
+ text-decoration: underline;
+}
+
+.code
+{
+ word-wrap: break-word;
+ margin: 10px;
+ padding: 10px;
+ border: 2px ridge white;
+ background-color: #eeeeee;
+ font-family: Courier New;
+ font-size: 10pt;
+}
View
33 stylesheets/pygments.css
@@ -0,0 +1,33 @@
+.hll { background-color: #ffffcc }
+.c { color: #008000 } /* Comment */
+.err { border: 1px solid #FF0000 } /* Error */
+.k { color: #0000ff } /* Keyword */
+.cm { color: #008000 } /* Comment.Multiline */
+.cp { color: #0000ff } /* Comment.Preproc */
+.c1 { color: #008000 } /* Comment.Single */
+.cs { color: #008000 } /* Comment.Special */
+.ge { font-style: italic } /* Generic.Emph */
+.gh { font-weight: bold } /* Generic.Heading */
+.gp { font-weight: bold } /* Generic.Prompt */
+.gs { font-weight: bold } /* Generic.Strong */
+.gu { font-weight: bold } /* Generic.Subheading */
+.kc { color: #0000ff } /* Keyword.Constant */
+.kd { color: #0000ff } /* Keyword.Declaration */
+.kn { color: #0000ff } /* Keyword.Namespace */
+.kp { color: #0000ff } /* Keyword.Pseudo */
+.kr { color: #0000ff } /* Keyword.Reserved */
+.kt { color: #2b91af } /* Keyword.Type */
+.s { color: #a31515 } /* Literal.String */
+.nc { color: #2b91af } /* Name.Class */
+.ow { color: #0000ff } /* Operator.Word */
+.sb { color: #a31515 } /* Literal.String.Backtick */
+.sc { color: #a31515 } /* Literal.String.Char */
+.sd { color: #a31515 } /* Literal.String.Doc */
+.s2 { color: #a31515 } /* Literal.String.Double */
+.se { color: #a31515 } /* Literal.String.Escape */
+.sh { color: #a31515 } /* Literal.String.Heredoc */
+.si { color: #a31515 } /* Literal.String.Interpol */
+.sx { color: #a31515 } /* Literal.String.Other */
+.sr { color: #a31515 } /* Literal.String.Regex */
+.s1 { color: #a31515 } /* Literal.String.Single */
+.ss { color: #a31515 } /* Literal.String.Symbol */
View
611 stylesheets/site.css
@@ -0,0 +1,611 @@
+/*Yahoo browser reset
+----------------------------------------------------------*/
+body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,
+blockquote,th,td {margin:0; padding:0; }
+table { border-collapse:collapse; border-spacing:0; }
+fieldset,img { border:0; }
+address,caption,cite,code,dfn,em,strong,th,var { font-style:normal; font-weight:normal; }
+ol,ul { list-style:none; }
+caption,th { text-align:left; }
+h1,h2,h3,h4,h5,h6 { font-size:100%; font-weight:normal; }
+/*q:before,q:after { content:”; }*/
+abbr,acronym { border:0; }
+
+/*Defaults
+----------------------------------------------------------*/
+html {height: 100%;}
+
+body {
+ font: normal 100% Frutiger, "Frutiger Linotype", Univers, Calibri, "Gill Sans", "Gill Sans MT", "Myriad Pro", Myriad, "DejaVu Sans Condensed", "Liberation Sans", "Nimbus Sans L", Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif;
+ height: 100%;
+ text-align:left;
+ color:#3e483c;
+}
+
+
+/* ---------- Headings and defaults ---------- */
+h1,h2,h3,h4,h5,h6,legend {padding:4px 0; font-family:"Palatino Linotype", Palatino, Palladio, "URW Palladio L", "Book Antiqua", Baskerville, "Bookman Old Style", "Bitstream Charter", "Nimbus Roman No9 L", Garamond, "Apple Garamond", "ITC Garamond Narrow", "New Century Schoolbook", "Century Schoolbook", "Century Schoolbook L", Georgia, serif; font-weight:normal; font-style: normal;color:#27320a;}
+
+h1 {font-size: 190%;}
+h2 {font-size: 150%;}
+h3 {font-size: 140%;}
+h4 {font-size: 125%;}
+h5 {font-size: 115%;}
+h6 {font-size: 105%;}
+
+p {line-height:20px; padding:2px 8px;}
+
+ul {list-style:disc outside; line-height:22px; padding:0 0 0 24px;}
+ol {list-style:decimal outside; line-height:22px; padding:0 0 0 24px;}
+
+strong {font-weight: bold;}
+em {font-style:italic;}
+
+#SidebarContentDiv ul {list-style:none; padding:0 0 0 12px;}
+
+.resulterror, .resulterror * {
+ color: #FF0000;
+}
+
+.resultok, .resultok * {
+ color: #009900;
+}
+
+input, label {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ color: #000000;
+ padding: 2px;
+ margin: 0px;
+}
+
+select {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ color: #000000;
+ margin: 0px;
+}
+
+input.tab {
+ background-color: #DDDDDD;
+ border: solid 3px #DDDDDD;
+ color: #000000;
+ font-size: 75%;
+ width: auto;
+ overflow: visible;
+ padding: 0px;
+}
+
+input.tabselected {
+ background-color: #214C9A;
+ border: solid 3px #214C9A;
+ color: #FFFFFF;
+ font-size: 75%;
+ width: auto;
+ overflow: visible;
+ font-weight: bold;
+ padding: 0px;
+}
+
+input.compact {
+ font-size: 75%;
+ padding: 0px;
+}
+
+#TabDiv {
+ border-bottom: solid 6px #214C9A;
+ margin-bottom: 10px;
+}
+
+/* Contains the date picks in the Edit.aspx page */
+#DatePickDiv {font-size: 75%; border: solid 1px #999999; background-color: #FFFFFF; padding: 2px;}
+
+a.datepicklink {display: block;}
+
+/* Small text */
+p.small, small {font-size: 75%;}
+
+/* Big text */
+p.big, big {font-size: 105%;}
+
+/* Description/legend for images */
+p.imagedescription {font: 75% italic; margin:4px 0 0 0;}
+
+/* ----------------------- links ----------------------------- */
+a, a:visited {color:#006699; text-decoration:none;}
+a:hover {text-decoration: underline;}
+a:active {color:#006699;}
+
+a.headeranchor {visibility: hidden;}
+
+h1.pagetitle, h1.pagetitlesystem {border-bottom:1px dashed #e4e7dc; margin-bottom:8px; padding-bottom:2px;}
+
+h1.pagetitlesystem {margin-bottom: 10px;}
+
+/* Class for applying a separator under H elements (useful to avoid usage of HR) */
+h1, h2, h3 {
+ border-bottom:1px dashed #e4e7dc;
+ padding-bottom: 2px;
+ margin-bottom: 8px;
+ margin-top: 19px;
+}
+
+a.editsectionlink {
+ float: right;
+ font-size: 75%;
+ margin: 4px 0px 0px 0px;
+}
+
+code, pre {
+ font-family: Courier New, Lucida Console, Monospace;
+ font-size:95%;
+ color: #000000;
+ padding: 0px;
+ margin: 0px;
+}
+
+pre {
+ border: dashed 1px #999999;
+ background-color: #FFFFF0;
+ margin: 10px 0;
+ padding: 8px;
+ overflow:auto;
+}
+
+table, div {
+ padding: 0px;
+ margin: 0px;
+}
+
+#PageContentDiv table {
+ border: 1px solid #CCC;
+ margin-top: 16px;
+ margin-bottom: 16px;
+}
+
+#PageContentDiv table thead td {
+ background-color: #DDD;
+ font-size: 0.8em;
+}
+
+#PageContentDiv table td {
+ font-size: 0.8em;
+ border: 1px solid #CCC;
+ padding: 3px;
+ margin: 0;
+}
+
+img {
+ border: none;
+}
+
+/* Class for general purpose images (contained in Wiki pages) */
+img.image {
+ border: solid 1px #CCCCCC;
+}
+
+/* Class of the formatting Buttons in Edit.aspx */
+img.format {
+ border: solid 1px;
+ padding: 2px;
+}
+
+/* Div used for clearing floats */
+div.clear {
+ clear: both;
+}
+
+/* Div containing images alighed to the left */
+div.imageleft {
+ border: solid 1px #CCCCCC;
+ background-color: #F9F9F9;
+ padding: 4px;
+ margin-left: 0px;
+ margin-right: 8px;
+ margin-top: 4px;
+ margin-bottom: 4px;
+ float: left;
+}
+
+/* Div containing images alighed to the right */
+div.imageright {
+ border: solid 1px #CCCCCC;
+ background-color: #F9F9F9;
+ padding: 4px;
+ margin-left: 8px;
+ margin-right: 0px;
+ margin-top: 4px;
+ margin-bottom: 4px;
+ float: right;
+}
+
+/* Table containing images not aligned */
+table.imageauto {
+ border: solid 1px #CCCCCC;
+ background-color: #F9F9F9;
+ padding: 4px;
+ margin: 4px 4px 4px 0px;
+}
+
+/* Div acting like a box */
+div.box {
+ border: solid 1px #CCCCCC;
+ background-color: #F9F9F9;
+ display: table-cell;
+ padding: 4px;
+ margin: 4px 4px 0px 4px;
+}
+
+/* Contains the Header */
+#HeaderDiv {
+ margin:0 auto;
+ padding: 0px;
+ height:134px;
+ background:url(images/background_header.jpg) no-repeat top center;
+}
+
+#branding {
+ width:960px;
+ display:block;
+ height:90px;
+ margin:0em auto;
+}
+
+#branding h1 {
+ border-bottom: none;
+ padding-bottom: 0;
+ margin-bottom: 0;
+ margin-top: 0;
+}
+
+#branding h1 a {
+ background:url(images/orchardLogo.jpg) no-repeat scroll 0 0;
+ float:left;
+ display:block;
+ width:216px;
+ height:90px;
+ position:relative;
+ top:-4px;
+ margin-bottom:-4px;
+ z-index:0;
+}
+
+#navMain{
+ width:960px;
+ display:block;
+ height:44px;
+ margin:0em auto;
+ clear:both;
+}
+
+/* Top navigation pane
+----------------------------------------------------------*/
+
+#navMain ul{
+ margin:0;
+ padding:0;
+ list-style:none;
+ float:left;
+}
+
+#navMain ul li {
+ float:left;
+ margin:0 8px;
+}
+
+#navMain ul li a, #navMain ul li a:visited, #navMain ul li a:active {
+ display:block;
+ padding:10px 12px 12px 12px;
+ color: #e2e4dd;
+ font-size:104%;
+ text-decoration: none;
+}
+
+
+#navMain ul li a:hover {
+ color:#ffea9b;
+}
+
+#navMain ul li.On {
+ background:url(images/tabOn.gif) no-repeat bottom center;
+ line-height: 22px;
+}
+
+
+
+/* Contains the SidebarDiv and the MainDiv */
+#ContainerDiv {
+ width:960px;
+ margin:0px auto;
+ background:url(Images/background_content.jpg) top center no-repeat #fff;
+ position: relative;
+ min-height: 100%;
+ height: 100%;
+ voice-family: "\"}\"";
+ voice-family: inherit;
+ height: auto;
+ overflow:auto;
+}
+
+html>body #ContainerDiv {height: auto;}
+
+/* Contains the Sidebar */
+#SidebarDiv {
+ float:right;
+ padding:34px 10px 10px 10px;
+ width:225px;
+ background:url(Images/background_module.gif) no-repeat bottom right;
+}
+
+#SidebarDiv h2 {
+ margin-top: 6px;
+}
+
+#SidebarDiv div {
+ margin-bottom: 19px;
+}
+
+/* Contains the contents of a Page */
+#MainDiv {
+ padding:12px 10px 10px 22px;
+ width:680px;
+}
+
+#MainDiv img {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+#MainFooterDiv {clear:both;}
+
+/* Contains the Page Header (title, last modify, etc.) */
+#PageHeaderDiv {}
+
+#PageInternalHeaderDiv {
+ margin-bottom: 10px;
+}
+
+#PageInternalFooterDiv {
+ margin-top: 10px;
+}
+
+/* Contains the link to the page editing form (Edit.aspx) and history */
+#EditHistoryLinkDiv {
+ float: right;
+ font-size: 75%;
+ padding: 24px 0 8px 0;
+}
+#EditLink, #HistoryLink, #ViewCodeLink, #DiscussLink, #BackLink, #PostReplyLink {
+ margin-left: 4px;
+ padding: 2px;
+ border: solid 1px #999999;
+ text-decoration: none;
+}
+#EditLink:hover, #HistoryLink:hover, #ViewCodeLink:hover, #DiscussLink:hover, #BackLink:hover, #PostReplyLink:hover {
+ border: solid 1px #214C9A;
+ text-decoration: none;
+ background-color: #FFFFEE;
+}
+
+/* Class of the P containing the Edit Link */
+p.editlink {font-size: 75%;}
+
+/* Contains the Page Content */
+#PageContentDiv {
+ margin: 10px 0px 0px 0px;
+ line-height:24px
+}
+
+/* Contains the Footer */
+#FooterDiv {
+ margin:0 auto;
+ padding:0px;
+ background:url(Images/background_footer.jpg) no-repeat scroll center top;
+ height:120px;
+ width:960px;
+ vertical-align:bottom;
+ text-align:center;
+}
+
+#FooterDiv p {
+ padding:80px 0 0 0;
+}
+
+#EditProviderListDiv {
+ float: right;
+}
+
+/* Contains the page preview in the Edit.aspx page */
+#PreviewDiv {
+}
+
+
+blockquote {
+ border-left: solid 8px #DDDDDD;
+ margin-left: 16px;
+ padding: 0px 0px 2px 6px;
+ margin: 10px 0 10px 0;
+}
+
+.search {padding:12px 0 0 12px;}
+
+#TxtSearchBox {
+ font-size: 75%;
+ width: 160px;
+ background: url(Images/Search.png) no-repeat right center #b2b89d;
+ background-color:#fff; /*Remove when search gets moved up to top branding area*/
+ margin:4px 0;
+ padding:3px;
+ border:1px solid #50553f;
+ color:#555;
+}
+
+#TxtSearchPage {
+ font-size: 75%;
+ width: 170px;
+ background-image: url(Images/Search.png);
+ background-repeat: no-repeat;
+ background-position: right center;
+ background-color: #FFFFFF;
+ border: solid 1px #CCCCCC;
+ margin: 1px;
+}
+
+span.signature {
+ font-style: italic;
+}
+
+.TocContainer {
+ border: solid 1px #CCCCCC;
+ padding: 4px;
+ background-color: #F9F9F9;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ margin-top: 20px;
+ margin-bottom: 20px;
+}
+
+.TocContainer ol {
+ list-style-type: none;
+ padding:0;
+}
+
+.TocContainer h1, .TocContainer h2, .TocContainer h3, .TocContainer h4, .TocContainer h5, .TocContainer h6 {
+ font-size: 0.8em;
+ border:none;
+ padding:0;
+ margin:0;
+}
+
+.TocContainer a:hover {
+ text-decoration: none;
+}
+
+.TocContainer h1 {
+}
+
+.TocContainer h2 {
+ margin-left: 8px;
+}
+
+.TocContainer h3 {
+ margin-left: 16px;
+}
+
+.TocContainer h4 {
+ margin-left: 24px;
+}
+
+.TocContainer h5 {
+ margin-left: 32px;
+}
+
+.TocContainer h6 {
+ margin-left: 40px;
+}
+
+/* Search page begin */
+
+#SearchCatExtDiv {
+ float: right;
+ margin-left: 15px;
+ background-color: #FFFFFF;
+}
+
+#SearchCatDiv {
+ border: solid 1px #999999;
+ padding: 2px;
+ max-height: 180px;
+ min-width: 200px;
+ overflow: auto;
+}
+
+#SearchControlsDiv {
+}
+
+#SearchInstructionsDiv, #SearchInstructionsDiv ul li {
+ font-size: 75%;
+}
+
+#SearchResultsDiv {
+ float: none;
+ min-height: 80px;
+}
+
+#SearchResultsDiv header {
+ font-size: 0.8em;
+}
+
+#SearchResultsDiv li {
+ list-style: none;
+}
+
+.searchPagination {
+ margin-top: 20px;
+}
+
+.searchPagination li {
+ list-style: none;
+ display: inline;
+}
+
+.searchButton {
+ border: none;
+ background: transparent;
+ font-size: 1.4em;
+ color: #006699;
+ cursor: pointer;
+}
+
+/* Search page end */
+
+#siteInfo {
+ bottom: 0;
+ width:100%;
+ display: block;
+}
+
+#siteInfoContent {
+ margin:0 auto;
+ background:url(images/background_footer.jpg) no-repeat center top;
+ height:120px;
+ width:960px;
+ vertical-align:bottom;
+ text-align:center;
+}
+
+
+#siteInfoContent ul{
+ padding:80px 0 0 0;
+ list-style:none;
+}
+
+#siteInfoContent ul li {
+ display:inline;
+ margin:0px;
+ padding: 0 8px;
+}
+
+/* Extensions
+----------------------------------------------------------*/
+
+.floatLeft {float: left;} /*Use this class to float anything to the left*/
+
+.floatRight {float: right;} /*Use this class to float anything to the right*/
+
+.alignRight {text-align: right;}
+
+.Inline {display: inline;}
+
+.center {margin:0 auto;} /*Center*/
+
+.clearLayout {clear:both;} /*Use this class clear layout*/
+
+.disabled {color:#CCC;}
+
+.topSpacer {margin-top: 30px;}
+
+.bottomSpacer {margin-bottom: 20px;}
+
+.displayText {display:none;}
View
23 tutorial/advanced-enterprise-features.md
@@ -0,0 +1,23 @@
+---
+title: 'Lesson 11: Advanced (Enterprise) Features'
+layout: default
+---
+
+## Clustering
+
+Clustering currently only works with the AdoJobstore (JobStoreTX). Features include load-balancing and job fail-over (if the JobDetail's "request recovery" flag is set to true).
+
+Enable clustering by setting the "quartz.jobStore.clustered" property to "true".
+Each instance in the cluster should use the same copy of the quartz properties.
+Exceptions of this would be to use properties that are identical, with the following allowable exceptions:
+Different thread pool size, and different value for the "quartz.scheduler.instanceId" property.
+Each node in the cluster MUST have a unique instanceId, which is easily done (without needing different properties files) by placing "AUTO" as the value of this property.
+
+Never run clustering on separate machines, unless their clocks are synchronized using some form of time-sync service (daemon) that runs very regularly
+(the clocks must be within a second of each other). See <a href="http://www.boulder.nist.gov/timefreq/service/its.htm">http://www.boulder.nist.gov/timefreq/service/its.htm</a>
+if you are unfamiliar with how to do this.
+
+Never fire-up a non-clustered instance against the same set of tables that any other instance is running against.
+You may get serious data corruption, and will definitely experience eratic behavior.
+
+[&laquo; Lesson 10](configuration-resource-usage-and-scheduler-factory.html) | [Lesson 12 &raquo;](miscellaneous-features.html)
View
68 tutorial/configuration-resource-usage-and-scheduler-factory.md
@@ -0,0 +1,68 @@
+---
+title: 'Lesson 10: Configuration, Resource Usage and SchedulerFactory'
+layout: default
+---
+
+Quartz is architected in modular way, and therefore to get it running, several components need to be "snapped" together.
+Fortunately, some helpers exist for making this happen.
+
+The major components that need to be configured before Quartz can do its work are:
+
+* ThreadPool
+* JobStore
+* DataSources (if necessary)
+* The Scheduler itself
+
+The ThreadPool provides a set of Threads for Quartz to use when executing Jobs.
+The more threads in the pool, the greater number of Jobs that can run concurrently.
+However, too many threads may bog-down your system.
+Most Quartz users find that 5 or so threads are plenty- because they have fewer than 100 jobs at any given time,
+the jobs are not generally scheduled to run at the same time, and the jobs are short-lived (complete quickly).
+Other users find that they need 10, 15, 50 or even 100 threads - because they have tens-of-thousands
+of triggers with various schedules - which end up having an average of between 10 and 100 jobs trying to
+execute at any given moment. Finding the right size for your scheduler's pool is completely dependent on
+what you're using the scheduler for. There are no real rules, other than to keep the number of threads as
+small as possible (for the sake of your machine's resources) - but make sure you have enough for your Jobs to fire on time.
+Note that if a trigger's time to fire arrives, and there isn't an available thread,
+Quartz will block (pause) until a thread comes available, then the Job will execute -
+some number of milliseconds later than it should have. This may even cause the tread to misfire - if
+there is no available thread for the duration of the scheduler's configured "misfire threshold".
+
+A IThreadPool interface is defined in the Quartz.Spi namespace, and you can create a IThreadPool implementation in any way you like.
+Quartz ships with a simple (but very satisfactory) thread pool named Quartz.Simpl.SimpleThreadPool.
+This IThreadPool implementation simply maintains a fixed set of threads in its pool - never grows, never shrinks.
+But it is otherwise quite robust and is very well tested - as nearly everyone using Quartz uses this pool.
+
+JobStores and DataSrouces were discussed in Lesson 9 of this tutorial. Worth noting here, is the fact that all JobStores
+implement the IJobStore interface - and that if one of the bundled JobStores does not fit your needs, then you can make your own.
+
+Finally, you need to create your Scheduler instance. The Scheduler itself needs to be given a name and handed
+instances of a JobStore and ThreadPool.
+
+## StdSchedulerFactory
+
+StdSchedulerFactory is an implementation of the ISchedulerFactory interface.
+It uses a set of properties (NameValueCollection) to create and initialize a Quartz Scheduler.
+The properties are generally stored in and loaded from a file, but can also be created by your program and handed directly to the factory.
+Simply calling getScheduler() on the factory will produce the scheduler, initialize it (and its ThreadPool, JobStore and DataSources),
+and return a handle to its public interface.
+
+There are some sample configurations (including descriptions of the properties) in the "docs/config" directory of the Quartz distribution.
+You can find complete documentation in the "Configuration" manual under the "Reference" section of the Quartz documentation.
+
+## DirectSchedulerFactory
+
+DirectSchedulerFactory is another SchedulerFactory implementation. It is useful to those wishing to create their Scheduler
+instance in a more programatic way. Its use is generally discouraged for the following reasons: (1) it
+requires the user to have a greater understanding of what they're doing, and (2) it does not allow for declaritive
+configuration - or in other words, you end up hard-coding all of the scheduler's settings.
+
+## Logging
+
+Quartz.NET uses the <a href="http://netcommon.sourceforge.net/">Common.Logging framework</a> for all of its logging needs.
+Quartz does not produce much logging information - generally just some information during initialization, and
+then only messages about serious problems while Jobs are executing. In order to "tune" the logging settings
+(such as the amount of output, and where the output goes), you need to understand the Commmon.Logging framework,
+which is beyond the scope of this document, please refer to <a href="http://netcommon.sourceforge.net/documentation.html">Common.Logging Documentation</a>.
+
+[&laquo; Lesson 9](job-stores.html) | [Lesson 11 &raquo;](advanced-enterprise-features.html)
View
99 tutorial/crontriggers.md
@@ -0,0 +1,99 @@
+---
+title: 'Lesson 6: CronTrigger'
+layout: default
+---
+
+CronTriggers are often more useful than SimpleTrigger, if you need a job-firing schedule that recurs based on calendar-like notions,
+rather than on the exactly specified intervals of SimpleTrigger.
+
+With CronTrigger, you can specify firing-schedules such as "every Friday at noon", or "every weekday and 9:30 am",
+or even "every 5 minutes between 9:00 am and 10:00 am on every Monday, Wednesday and Friday".
+
+Even so, like SimpleTrigger, CronTrigger has a startTime which specifies when the schedule is in force, and an (optional)
+endTime that specifies when the schedule should be discontinued.
+
+### Cron Expressions
+
+Cron-Expressions are used to configure instances of CronTrigger. Cron-Expressions are strings that are actually made up
+of seven sub-expressions, that describe individual details of the schedule. These sub-expression are separated with white-space, and represent:
+
+* 1. Seconds
+* 2. Minutes
+* 3. Hours
+* 4. Day-of-Month
+* 5. Month
+* 6. Day-of-Week
+* 7. Year (optional field)
+
+An example of a complete cron-expression is the string "0 0 12 ? * WED" - which means "every Wednesday at 12:00 pm".
+
+Individual sub-expressions can contain ranges and/or lists. For example, the day of week field in the previous (which reads "WED")
+example could be replaces with "MON-FRI", "MON, WED, FRI", or even "MON-WED,SAT".
+
+Wild-cards (the '*' character) can be used to say "every" possible value of this field. Therefore the '*' character in the
+"Month" field of the previous example simply means "every month". A '*' in the Day-Of-Week field would obviously mean "every day of the week".
+
+All of the fields have a set of valid values that can be specified. These values should be fairly obvious - such as the numbers
+0 to 59 for seconds and minutes, and the values 0 to 23 for hours. Day-of-Month can be any value 0-31, but you need to be careful
+about how many days are in a given month! Months can be specified as values between 0 and 11, or by using the strings
+JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC. Days-of-Week can be specified as vaules between 1 and 7 (1 = Sunday)
+or by using the strings SUN, MON, TUE, WED, THU, FRI and SAT.
+
+The '/' character can be used to specify increments to values. For example, if you put '0/15' in the Minutes field, it means 'every 15 minutes,
+starting at minute zero'. If you used '3/20' in the Minutes field, it would mean 'every 20 minutes during the hour,
+starting at minute three' - or in other words it is the same as specifying '3,23,43' in the Minutes field.
+
+The '?' character is allowed for the day-of-month and day-of-week fields. It is used to specify "no specific value".
+This is useful when you need to specify something in one of the two fields, but not the other.
+See the examples below (and CronTrigger API documentation) for clarification.
+
+The 'L' character is allowed for the day-of-month and day-of-week fields. This character is short-hand for "last",
+but it has different meaning in each of the two fields. For example, the value "L" in the day-of-month field means
+"the last day of the month" - day 31 for January, day 28 for February on non-leap years. If used in the day-of-week field by itself,
+it simply means "7" or "SAT". But if used in the day-of-week field after another value, it means "the last xxx day of the month" -
+for example "6L" or "FRIL" both mean "the last friday of the month". When using the 'L' option, it is important not to specify lists,
+or ranges of values, as you'll get confusing results.
+
+The 'W' is used to specify the weekday (Monday-Friday) nearest the given day. As an example, if you were to specify "15W" as the value for the day-of-month field, the meaning is: "the nearest weekday to the 15th of the month".
+
+The '#' is used to specify "the nth" XXX weekday of the month. For example, the value of "6#3" or "FRI#3" in the day-of-week field means "the third Friday of the month".
+
+## Example Cron Expressions
+
+Here are a few more examples of expressions and their meanings - you can find even more in the API documentation for CronTrigger
+
+**CronTrigger Example 1 - an expression to create a trigger that simply fires every 5 minutes**
+
+ "0 0/5 * * * ?"
+
+**CronTrigger Example 2 - an expression to create a trigger that fires every 5 minutes, at 10 seconds after the minute (i.e. 10:00:10 am, 10:05:10 am, etc.).**
+
+ "10 0/5 * * * ?"
+
+**CronTrigger Example 3 - an expression to create a trigger that fires at 10:30, 11:30, 12:30, and 13:30, on every Wednesday and Friday.**
+
+ "0 30 10-13 ? * WED,FRI"
+
+**CronTrigger Example 4 - an expression to create a trigger that fires every half hour between the hours of 8 am and 10 am on the 5th and 20th of every month.
+Note that the trigger will NOT fire at 10:00 am, just at 8:00, 8:30, 9:00 and 9:30**
+
+ "0 0/30 8-9 5,20 * ?"
+
+Note that some scheduling requirements are too complicated to express with a single trigger - such as "every 5 minutes between 9:00 am and 10:00 am,
+and every 20 minutes between 1:00 pm and 10:00 pm". The solution in this scenario is to simply create two triggers, and register both of them to run the same job.
+
+
+### CronTrigger Misfire Instructions
+
+The following instructions can be used to inform Quartz what it should do when a misfire occurs for CronTrigger.
+(Misfire situations were introduced in the More About Triggers section of this tutorial). These instructions are defined in MisfireInstruction.CronTrigger as
+constants (and API documentation has description for their behavior). The instructions include:
+
+* DoNothing
+* FireOnceNow
+
+All triggers have the MisfireInstrution.SmartPolicy instruction available for use, and this instruction is also the default for all trigger types.
+The 'smart policy' instruction is interpreted by CronTrigger as MisfireInstruction.CronTrigger.FireOnceNow. The API documentation for the
+CronTrigger.UpdateAfterMisfire() method explains the exact details of this behavior.
+
+[&laquo; Lesson 5](simpletriggers.html) | [Lesson 7 &raquo;](trigger-and-job-listeners.html)
View
22 tutorial/index.md
@@ -0,0 +1,22 @@
+---
+title: The Official Quartz.NET Tutorial
+layout: default
+---
+
+
+# The Official Quartz.NET Tutorial
+
+Choose a lesson:
+
+* [Lesson 1: Using Quartz](using-quartz.html)
+* [Lesson 2: Jobs And Triggers](jobs-and-triggers.html)
+* [Lesson 3: More About Jobs & JobDetails](more-about-jobs.html)
+* [Lesson 4: More About Triggers](~/Tutorial/More-About-Triggers)
+* [Lesson 5: SimpleTriggers](~/Tutorial/SimpleTriggers)
+* [Lesson 6: CronTriggers](~/Tutorial/CronTriggers)
+* [Lesson 7: TriggerListeners & JobListeners](~/Tutorial/TriggerListeners)
+* [Lesson 8: SchedulerListeners](~/Tutorial/SchedulerListeners)
+* [Lesson 9: JobStores](~/Tutorial/JobStores)
+* [Lesson 10: Configuration, Resource Usage and SchedulerFactory](~/Tutorial/Configuration-Resource-Usage-And-SchedulerFactory)
+* [Lesson 11: Advanced (Enterprise) Features](~/Tutorial/Advanced-Enterprise-Features)
+* [Lesson 12: Miscellaneous Features](~/Tutorial/Miscellaneous-Features)
View
118 tutorial/job-stores.md
@@ -0,0 +1,118 @@
+---
+title: 'Lesson 9: JobStores'
+layout: default
+---
+
+JobStore's are responsible for keeping track of all the "work data" that you give to the scheduler:
+jobs, triggers, calendars, etc. Selecting the appropriate IJobStore implementation for your Quartz scheduler instance is an important step.
+Luckily, the choice should be a very easy one once you understand the differences between them.
+You declare which JobStore your scheduler should use (and it's configuration settings) in the properties file (or object) that
+you provide to the SchedulerFactory that you use to produce your scheduler instance.
+
+Never use a JobStore instance directly in your code. For some reason many people attempt to do this.
+The JobStore is for behind-the-scenes use of Quartz itself. You have to tell Quartz (through configuration) which JobStore to use, but then you should only work with the Scheduler interface in your code.
+
+
+## RAMJobStore
+
+RAMJobStore is the simplest JobStore to use, it is also the most performant (in terms of CPU time).
+RAMJobStore gets its name in the obvious way: it keeps all of its data in RAM. This is why it's lightning-fast,
+and also why it's so simple to configure. The drawback is that when your application ends (or crashes) all of
+the scheduling information is lost - this means RAMJobStore cannot honor the setting of "non-volatility" on jobs and triggers.
+For some applications this is acceptable - or even the desired behavior, but for other applications, this may be disasterous.
+
+To use RAMJobStore (and assuming you're using StdSchedulerFactory) you don't need to do anything special. Default configuration
+of Quartz.NET uses RAMJobStore as job store implementation.
+
+## ADO.NET Job Store (AdoJobStore)
+
+AdoJobStore is also aptly named - it keeps all of its data in a database via ADO.NET.
+Because of this it is a bit more complicated to configure than RAMJobStore, and it also is not as fast.
+However, the performance draw-back is not terribly bad, especially if you build the database tables with indexes on the primary keys.
+
+To use AdoJobStore, you must first create a set of database tables for Quartz.NET to use.
+You can find table-creation SQL scripts in the "database/dbtables" directory of the Quartz.NET distribution.
+If there is not already a script for your database type, just look at one of the existing ones, and modify it in any way necessary for your DB.
+One thing to note is that in these scripts, all the the tables start with the prefix "QRTZ_"
+such as the tables "QRTZ_TRIGGERS", and "QRTZ_JOB_DETAIL"). This prefix can actually be anything you'd like, as long as you inform AdoJobStore
+what the prefix is (in your Quartz.NET properties). Using different prefixes may be useful for creating multiple sets of tables,
+for multiple scheduler instances, within the same database.
+
+Currently the only option for the internal implementation of job store is JobStoreTX which creates transactions by itself.
+This is different from Java version of Quartz where there is also option to choose JobStoreCMT which uses J2EE container
+managed transactions.
+
+The last piece of the puzzle is setting up a data source from which AdoJobStore can get connections to your database.
+Data sources are defined in your Quartz.NET properties. Data source information contains the connection string
+and ADO.NET delegate information.
+
+**Configuring Quartz to use JobStoreTx**
+
+ quartz.jobStore.type = Quartz.Impl.AdoJobStore.JobStoreTX, Quartz
+
+Next, you need to select a IDriverDelegate implementation for the JobStore to use.
+The DriverDelegate is responsible for doing any ADO.NET work that may be needed for your specific database.
+StdAdoDelegate is a delegate that uses "vanilla" ADO.NET code (and SQL statements) to do its work.
+If there isn't another delegate made specifically for your database, try using this delegate -
+special delegates usually have better performance or workarounds for database specific issues.
+Other delegates can be found in the "Quartz.Impl.AdoJobStore" namespace, or in its sub-namespaces.
+
+**NOTE:** Quartz.NET will issue warning if you are using the default StdAdoDelegate as it has poor performance
+when you have a lot of triggers to select from. Specific delegates have special SQL to limit result
+set length (SQLServerDelegate uses TOP n, PostgreSQLDelegate LIMIT n, OracleDelegate ROWCOUNT() <= n etc.).
+
+Once you've selected your delegate, set its class name as the delegate for AdoJobStore to use.
+
+**Configuring AdoJobStore to use a DriverDelegate**
+
+ quartz.jobStore.driverDelegateType = Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz
+
+Next, you need to inform the JobStore what table prefix (discussed above) you are using.
+
+**Configuring AdoJobStore with the Table Prefix**
+
+ quartz.jobStore.tablePrefix = QRTZ_
+
+And finally, you need to set which data source should be used by the JobStore. The named data source must also be defined in your Quartz properties.
+In this case, we're specifying that Quartz should use the data source name "myDS" (that is defined elsewhere in the configuration properties).
+
+**Configuring AdoJobStore with the name of the data source to use**
+
+ quartz.jobStore.dataSource = myDS
+
+One last thing that is needed for the configuration is to set data source connection string information and database provider. Connection
+string is the standard ADO.NET connection which is driver specific. Database provider is an abstraction of database drivers to create
+loose coupling betweeb database drivers and Quartz.
+
+**Setting Data Source's Connection String And Database Provider**
+
+ quartz.dataSource.myDS.connectionString = Server=localhost;Database=quartz;Uid=quartznet;Pwd=quartznet
+ quartz.dataSource.myDS.provider = MySql-50
+
+Currently following database providers are supported:
+
+* SqlServer-11 - SQL Server driver for .NET Framework 1.1
+* SqlServer-20 - SQL Server driver for .NET Framework 2.0
+* OracleClient-20 - Microsoft's Oracle Driver (comes bundled with .NET Framework)
+* OracleODP-20 - Oracle's Oracle Driver
+* MySql-10 - MySQL Connector/.NET v. 1.0.7
+* MySql-109 - MySQL Connector/.NET v. 1.0.9
+* MySql-50 - MySQL Connector/.NET v. 5.0 (.NET 2.0)
+* MySql-51 - MySQL Connector/:NET v. 5.1 (.NET 2.0)
+* SQLite-10 - SQLite ADO.NET 2.0 Provider v. 1.0.56 (.NET 2.0)
+* Firebird-201 - Firebird ADO.NET 2.0 Provider v. 2.0.1 (.NET 2.0)
+* Firebird-210 - Firebird ADO.NET 2.0 Provider v. 2.1.0 (.NET 2.0)
+
+If your Scheduler is very busy (i.e. nearly always executing the same number of jobs as the size of the thread pool, then you should
+probably set the number of connections in the data source to be the about the size of the thread pool + 1.This is commonly configured
+int the ADO.NET connection string - see your driver implementation for details.
+
+The "quartz.jobStore.useProperties" config parameter can be set to "true" (defaults to false) in order to instruct AdoJobStore that all values in JobDataMaps will be strings,
+and therefore can be stored as name-value pairs, rather than storing more complex objects in their serialized form in the BLOB column. This is much safer in the long term,
+as you avoid the class versioning issues that there are with serializing your non-String classes into a BLOB.
+
+**Configuring AdoJobStore to use strings as JobDataMap values (recommended)**
+
+ quartz.jobStore.useProperties = true
+
+[&laquo; Lesson 8](scheduler-listeners.html) | [Lesson 10 &raquo;](configuration-resource-usage-and-scheduler-factory.html)
View
66 tutorial/jobs-and-triggers.md
@@ -0,0 +1,66 @@
+---
+title: 'Lesson 2: Jobs And Triggers'
+layout: default
+---
+
+As mentioned previously, you can make .NET component executable by the scheduler simply by making it
+implement the IJob interface. Here is the interface:
+
+__IJob Interface__
+
+```c#
+ namespace Quartz
+ {
+ public interface IJob
+ {
+ void Execute(JobExecutionContext context);
+ }
+ }
+```
+
+In case you couldn't guess, when the job's trigger fires (more on that in a moment), the Execute(..) method
+is invoked by the scheduler. The JobExecutionContext object that is passed to this method provides
+the job instance with information about its "run-time" environment - a handle to the IScheduler that executed it,
+a handle to the Trigger that triggered the execution, the job's JobDetail object, and a few other items.
+
+The JobDetail object is created by the Quartz.NET client (your program) at the time the Job is added
+to the scheduler. It contains various property settings for the Job, as well as a JobDataMap, which can be used
+to store state information for a given instance of your job class.
+
+Trigger objects are used to trigger the execution (or 'firing') of jobs. When you wish to schedule a job,
+you instantiate a trigger and 'tune' its properties to provide the scheduling you wish to have.
+Triggers may also have a JobDataMap associated with them - this is useful to passing parameters to a Job
+that are specific to the firings of the trigger. Quartz.NET ships with a handful of different trigger types,
+but the most commonly used types are SimpleTrigger and CronTrigger.
+
+SimpleTrigger is handy if you need 'one-shot' execution (just single execution of a job at a given moment in time),
+or if you need to fire a job at a given time, and have it repeat N times, with a delay of T between executions.
+CronTrigger is useful if you wish to have triggering based on calendar-like schedules - such as "every Friday,
+at noon" or "at 10:15 on the 10th day of every month."
+
+## Why Jobs AND Triggers?
+
+Many job schedulers do not have separate notions of jobs and triggers. Some define a 'job' as simply an
+execution time (or schedule) along with some small job identifier. Others are much like the union
+of Quartz.NET's job and trigger objects. While developing Quartz for Java, Quartz team decided that it made sense to create
+a separation between the schedule and the work to be performed on that schedule. This has (in our opinion)
+many benefits.
+
+For example, jobs can be created and stored in the job scheduler independent of a trigger, and many triggers
+can be associated with the same job. Another benefit of this loose-coupling is the ability to configure jobs
+that remain in the scheduler after their associated triggers have expired, so that that it can be rescheduled
+later, without having to re-define it. It also allows you to modify or replace a trigger without having to
+re-define its associated job.
+
+## Identifiers
+
+Jobs and Triggers are given identifying names as they are registered with the Quartz.NET scheduler.
+Jobs and triggers can also be placed into 'groups' which can be useful for organizing your jobs and triggers
+into categories for later maintenance. The name of a job or trigger must be unique within its group - or in other
+words, the true identifier of a job or trigger is its name + group. If you leave the group of the
+Job or Trigger 'null', it is equivalent to having specified SchedulerConstants.DefaultGroup.
+
+You now have a general idea about what Jobs and Triggers are, you can learn more about them in
+[Lesson 3: More About Jobs & JobDetails](more-about-jobs.html) and [Lesson 4: More About Triggers](more-about-triggers.html)
+
+[&laquo; Lesson 1](using-quartz.html) | [Lesson 3 &raquo;](more-about-jobs.html)
View
5 tutorial/lesson_1.md
@@ -0,0 +1,5 @@
+---
+title: JobStores
+redirect: tutorial/using-quartz.html
+layout: redirect
+---
View
5 tutorial/lesson_10.md
@@ -0,0 +1,5 @@
+---
+title: JobStores
+redirect: tutorial/configuration-resource-usage-and-scheduler-factory.html
+layout: redirect
+---
View
5 tutorial/lesson_11.md
@@ -0,0 +1,5 @@
+---
+title: JobStores
+redirect: tutorial/advanced-enterprise-features.html
+layout: redirect
+---
View
5 tutorial/lesson_12.md
@@ -0,0 +1,5 @@
+---
+title: JobStores
+redirect: tutorial/miscellaneous-features.html
+layout: redirect
+---
View
5 tutorial/lesson_2.md
@@ -0,0 +1,5 @@
+---
+title: JobStores
+redirect: tutorial/jobs-and-triggers.html
+layout: redirect
+---
View
5 tutorial/lesson_3.md
@@ -0,0 +1,5 @@
+---
+title: JobStores
+redirect: tutorial/more-about-jobs.html
+layout: redirect
+---
View
5 tutorial/lesson_4.md
@@ -0,0 +1,5 @@
+---
+title: JobStores
+redirect: tutorial/more-about-triggers.html
+layout: redirect
+---
View
5 tutorial/lesson_5.md
@@ -0,0 +1,5 @@
+---
+title: JobStores
+redirect: tutorial/simpletriggers.html
+layout: redirect
+---
View
5 tutorial/lesson_6.md
@@ -0,0 +1,5 @@
+---
+title: JobStores
+redirect: tutorial/crontriggers.html
+layout: redirect
+---
View
5 tutorial/lesson_7.md
@@ -0,0 +1,5 @@
+---
+title: JobStores
+redirect: tutorial/trigger-and-job-listeners.html
+layout: redirect
+---
View
5 tutorial/lesson_8.md
@@ -0,0 +1,5 @@
+---
+title: JobStores
+redirect: tutorial/scheduler-listeners.html
+layout: redirect
+---
View
5 tutorial/lesson_9.md
@@ -0,0 +1,5 @@
+---
+title: JobStores
+redirect: tutorial/job-stores.html
+layout: redirect
+---
View
31 tutorial/miscellaneous-features.md
@@ -0,0 +1,31 @@
+---
+title: 'Lesson 12: Miscellaneous Features of Quartz'
+layout: default
+---
+
+## Plug-Ins
+
+Quartz provides an interface (ISchedulerPlugin) for plugging-in additional functionality.
+
+Plugins that ship with Quartz to provide various utililty capabilities can be found documented in the Quartz.Plugins namespace.
+They provide functionality such as auto-scheduling of jobs upon scheduler startup, logging a history of job and trigger events,
+and ensuring that the scheduler shuts down cleanly when the virtual machine exits.
+
+## JobFactory
+
+When a trigger fires, the Job it is associated to is instantiated via the JobFactory configured on the Scheduler.
+The default JobFactory simply activates a new instance of the job class. You may want to create your own implementation
+of JobFactory to accomplish things such as having your application's IoC or DI container produce/initialize the job instance.
+
+See the IJobFactory interface, and the associated Scheduler.SetJobFactory(fact) method.
+
+## 'Factory-Shipped' Jobs
+
+Quartz also provides a number of utility Jobs that you can use in your application for doing things like sending
+e-mails and invoking remote objects. These out-of-the-box Jobs can be found documented in the Quartz.Jobs namespace.
+
+[&laquo; Lesson 11](advanced-enterprise-features.html)
+
+
+
+
View
183 tutorial/more-about-jobs.md
@@ -0,0 +1,183 @@
+---
+title: 'Lesson 3: More About Jobs & JobDetails'
+layout: default
+---
+
+As you've seen, jobs are rather easy to implement. There are just a few more things that you need to understand about
+the nature of jobs, about the Execute(..) method of the IJob interface, and about JobDetails.
+
+While a class that you implement is the actual "job", Quartz needs to be informed about various attributes
+that you may wish the job to have. This is done via the JobDetail class, which was mentioned briefly in the previous section.
+Software 'archaeologists' may be interested to know that in an older incarnation of Quartz for Java, the implementation of the
+functionality of JobDetail was imposed upon the implementor of each Job class by having all of JobDetail's 'getter' methods on