Skip to content

Simplify.Scheduler

Alexanderius edited this page May 20, 2023 · 10 revisions

Simplify.Scheduler Documentation

Same as Simplify.WindowsServices library with removed Windows Services dependency and specifically made for console (docker) execution.

Provides BasicScheduler, SingleTaskScheduler, MultitaskScheduler classes for scheduling.

Allows you to simply create applications which can work on schedule. Every user class instance will be instantiated using Simplify.DI IOC container which provides DI by default for your application.

Available at NuGet as binary package

Principle of work

To use Simplify.Scheduler, you must create a class with the Run method in it and pass this class to the handler as a type parameter. The Run method will be invoked by the handler class (the handler types are listed below), this method will be your execution process root. An instance of your class will be created using the IOC Simplify.DI container, so you can register any types that your class depends on through DIContainer.Current, and they will be automatically resolved.

Run method can be one of the following:

  • Parameterless Run() method.
  • Run(string serviceName) if you want to access a service name.
  • Run(IJobArgs args) if you want to access a service name or startup parameters.

Run method can be void or can return Task (can be used for async/await code).

Quick start

There is a templates package available at nuget.org for Simplify.Scheduler.

Install Simplify.ProjectsTemplates templates package:

dotnet new -i Simplify.ProjectsTemplates

Create an initial Simplify.Scheduler based project:

dotnet new simplify.scheduler -n HelloWorld

Types of Schedulers

BasicScheduler

BasicScheduler class is best suited for services that run without timers, for example, a TCP server or client.

SingleTaskScheduler

SingleTaskScheduler class is best suited to perform one task, which must be periodically started by a timer.

MultitaskScheduler

MultitaskScheduler class is best suited for multiple tasks services.

This is the same as SingleTaskScheduler but allows you to specify multiple working classes/methods. You can add multiple jobs with different timer intervals/crontab expressions.

You can use single class with several methods, each specified method will be launched by the corresponding task (a new instance of the class will be created), or simply use several classes.

MultitaskScheduler working example

Setup a job schedule

You can specify timer intervals in seconds or just set the Ncrontab expression for timer. If no settings specified in the configuration, then the timer will be executed once every minute. If both timer interval and crontab expression specified in the config, then the crontab expression will be used instead.

Multiple crontab expressions can be specified, for example: 30 14 * * *|45 1 * * *|0 12 * * Mon

The main way to setup a job is to pass configuration based on Microsoft.Extensions.Configuration.IConfiguration

Example

Program.cs

var configuration = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json", false)
    .Build();

using(var handler = new SingleTaskScheduler<MyClass>(configuration))
    handler.Start();

appsettings.json

{
    "JobSettings":
    {
        "CrontabExpression": "* * * * *",
        "ProcessingInterval: 30
    }
}

Additional settings

Option default value Description
CleanupOnTaskFinish true Execute GC.Collect(); after each "Run" method execution
MaximumParallelTasksCount 1 (so the only one task of the same job can exist at a time) The maximum allowed parallel tasks of the same job (the new task will be create in parallel if previous task is not ended execution)

Global exceptions catching which can be thrown when resolving instances by Simplify.DI in handler

Simplify.Scheduler can catch all exceptions thrown by user code. To receive such an event you should subscribe to handler OnException event.

static void Main(string[] args)
{
    ...
    handler.OnException += OnException;
    ...
}

static void OnException(ServiceExceptionArgs args)
{
    Console.Write(args.ServiceName);
    Console.Write(args.Exception.Message);
}

Examples

BasicScheduler

MyClass.cs

public class MyClass
{
    public void Run()
    {
        // Some task
    }
}

Program.cs

static void Main(string[] args)
{
    DIContainer.Current.Register<MyClass>();

    using(var scheduler = new BasicScheduler<MyClass>())
        scheduler.Start(args)
}

SingleTaskScheduler

static void Main(string[] args)
{
    DIContainer.Current.Register<MyClass>();

    using(var scheduler = new SingleTaskScheduler<MyClass>)
        scheduler.Start(args);
}

MultitaskScheduler

Program.cs

static void Main(string[] args)
{
    // Registering in IOC container

    DIContainer.Current.Register<TaskProcessor1>();
    DIContainer.Current.Register<TaskProcessor2>();

   // Handler creation
    using(var handler = new MultitaskScheduler())
    {
        // Jobs addition

        // If configuration section is not specified then 'YourClassName + Settings' section name will be used
        handler.AddJob<TaskProcessor1>();

        // Manually specified section name and invoke method name
        handler.AddJob<TaskProcessor1>("TaskProcessor1SecondTaskSettings", "RunTask2");

        handler.AddJob<TaskProcessor2>();

        handler.Start(args);
    }
}

TaskProcessor1.cs

public class TaskProcessor1
{
    public void Run()
    {
        Debug.WriteLine("TaskProcessor1 Run executed");
    }

    public void RunTask2()
    {
        Debug.WriteLine("TaskProcessor1 RunTask2 executed");
    }
}

TaskProcessor2.cs

public class TaskProcessor2
{
    public void Run()
    {
        Debug.WriteLine("TaskProcessor2 Run executed");
    }
}

appsettings.json

{
  "TaskProcessor1Settings": {
    "CrontabExpression": "*/2 * * * *"
  },
  "TaskProcessor1SecondTaskSettings": {
    "ProcessingInterval": 30
  },
  "TaskProcessor2Settings": {
    "ProcessingInterval": 45
  }
}