Click here to Skip to main content
15,881,852 members
Articles / Programming Languages / C#
Article

Implementing a small Cron service in C#

Rate me:
Please Sign up or sign in to vote.
4.13/5 (17 votes)
14 Jul 20053 min read 148.8K   3.8K   51   18
This article shows how to use the attached C# Cron class to implement a small Cron service.

Introduction

The Cron class provided with this article implements a small and effective Cron implementation for Windows.

Background

You can schedule the execution of Windows programs using the Scheduled Tasks Control Panel application, and there are already many CodeProject articles related to scheduling in other fashions. So if you are reading this article, I am going to assume that you already have your reasons to implement Cron-style scheduling in C#.

This Cron scheduler is originally part of an application I created for my work, but I have separated out the Cron class for this article. (BTW, I have written the code using Java-style initialCaps on the methods and associations. You'll just have to live with that or change it yourself.)

Using the code

The Cron scheduler is implemented in a single class, CronService.Cron (CronService is the namespace I thought up for this article, but you may want to change this into the default namespace for your Cron application).

You can start an instance of this class using the start() method, which simply starts the scheduler and never returns. For instance, you can link the code below with the Cron class to create a regular Windows executable (for use in Windows' Startup Programs folder, for example):

C#
using System;

namespace CronService
{
    class CronMain
    {
        [STAThread]
        static void Main(string[] args)
        {
            Cron cron = new Cron ();
            cron.start ();
        }
    }
}

I could imagine that you want to create a Windows service instead. To learn how that is done, I recommend the CodeProject tutorial Creating a C# Service Step-by-Step by Terry Denham.

Once you have set up a Windows service like described there, it is a simple matter of filling in the template ServiceBase class that you have created. There is only one small caveat: the OnStart method that you will implement here, is expected to return after 20 seconds or so, so you will have to start the perpetually running scheduler in a separate thread.

The example below provides you with a very stripped down version of doing just that. Please use this code only as a hint when creating your own service.

C#
using System.Threading;

namespace CronService
{
    public class CronService : System.ServiceProcess.ServiceBase
    {
        private Cron cron;
        private Thread thr;

        public RecoveryService()
        {
            cron = new Cron ();
            thr = new Thread ( new ThreadStart (cron.start));
            thr.Name = "cron";
        }

        protected override void OnStart(string[] args)
        {
            thr.Start ();
        }
 
        protected override void OnStop()
        {
            thr.Abort();
        }
    }
}

Creating a valid Cron file

The Cron class reads a file cron.tab from its current directory. The syntax of this file is as good as compatible with that described in the UNIX manpage crontab(5).

Environment variables and percentage signs for newlines are not supported, and, unlike the original Cron, the command line is not interpreted by a shell. Instead, the first word is assumed to be the executable, and the rest is passed as arguments to this executable using the System.Diagnostics.Process API.

As crontab fields are separated by whitespace, a single preceding backslash may be used to escape a space character in the command field. And to be complete, a double backslash may be used to escape a single backslash when it's unfortunately placed before an unsuspecting space character. At any other place, a single backslash will do just fine.

An example:

# DoThis every hour
0 * * * * C:\Program\ Files\MyProg\DoThis.exe arg1 arg2
# DoThat -- well, you figure out when :-)
8-9/2 12,13,14-18 * * * C:\Program\ Files\MyProg\DoThat.exe

Points of Interest

The Cron class is small and effective, but did I mention small? There are some limitations that you should be aware of:

  • Cron only reads the cron.tab file at startup. You need to restart Cron if you want changes to cron.tab to become effective. There are no multiple crontabs, nor is there a crontab(1) command.
  • Cron does not mail any program output to the system administrator, as you may be used to from UNIX. Instead, it only reports when a program exits with a nonzero exit code.
  • The reportError() function is left empty as an exercise to the reader.

Closing note: while Paul Vixie achieved immortality with his Cron implementation, I wrote mine in a single day or so. This is of course mainly due to the advanced DateTime and String functions available in the .NET API.

The code within this tutorial is free to use, but please, credit where credit is due.

History

  • July 14, 2005 -- First version of this article.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Netherlands Netherlands
Stefan Rieken (The Netherlands, 1980) is a software programmer, currently employed at at a University hospital. While his private taste goes out to Open Source solutions, in everyday work you can see him using a wide variety of development environments.

In private life, he enjoys making music, cartoons (too little of those lately) and Free Software projects involving experimental OO language design.

Comments and Discussions

 
QuestionCron and C# Pin
Kamal Maroc16-Jul-13 23:32
Kamal Maroc16-Jul-13 23:32 
GeneralCongratulations Pin
tuca.ssa18-Mar-09 4:45
tuca.ssa18-Mar-09 4:45 
GeneralMonth Day Problem [modified] Pin
mribbons22-Feb-09 12:08
mribbons22-Feb-09 12:08 
QuestionHow to retrieve Next Run Date? Pin
vishal.tanwar21-Jul-08 19:47
vishal.tanwar21-Jul-08 19:47 
NewsI've implemented your solution in my cronBI project Pin
tregnago13-Feb-08 4:26
tregnago13-Feb-08 4:26 
GeneralMultiple executions within one minute Pin
phorvat30-Jul-07 2:00
phorvat30-Jul-07 2:00 
QuestionBug missing multiple minutes? Pin
tekHedd11-Apr-06 18:42
tekHedd11-Apr-06 18:42 
AnswerHow could it skip multiple minutes? Pin
tekHedd11-Apr-06 18:43
tekHedd11-Apr-06 18:43 
GeneralRe: How could it skip multiple minutes? Pin
Stefan Rieken11-Apr-06 22:43
Stefan Rieken11-Apr-06 22:43 
GeneralDoThat -- well, you figure out when :-) Pin
MrEyes14-Feb-06 13:35
MrEyes14-Feb-06 13:35 
GeneralRe: DoThat -- well, you figure out when :-) Pin
Stefan Rieken11-Apr-06 21:55
Stefan Rieken11-Apr-06 21:55 
Well, as you figured out, I had a good reason not to get into this example Wink | ;-) It just goes to show the syntactical possibilities; it's not meant to be practical or anything.

-- modified at 4:45 Wednesday 12th April, 2006
GeneralThanks Pin
claykeller15-Nov-05 17:40
claykeller15-Nov-05 17:40 
Questionusing reportError function Pin
AXELDE20-Oct-05 12:47
AXELDE20-Oct-05 12:47 
AnswerRe: using reportError function Pin
Stefan Rieken23-Oct-05 22:59
Stefan Rieken23-Oct-05 22:59 
AnswerRe: using reportError function Pin
AXELDE24-Oct-05 9:56
AXELDE24-Oct-05 9:56 
GeneralGood first article Pin
Donsw23-Jul-05 5:38
Donsw23-Jul-05 5:38 
GeneralCool! Pin
|[awx]|20-Jul-05 18:43
|[awx]|20-Jul-05 18:43 
GeneralUnix Flav! Pin
jmsmac15-Jul-05 2:44
jmsmac15-Jul-05 2:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.