Feedback

C# - simple scheduler

Veröffentlicht von am 29.08.2008
(1 Bewertungen)
simpler scheduler
using System;
using System.Collections.Generic;
using System.Threading;
using System.Timers;

namespace NetSnippetsQuickTest
{
    public interface ICommand
    {
        bool Execute();
        Guid Id { get; }
    }

    class Scheduler
    {
        List<ICommand> _commands;
        public readonly double SchedulingIntervalInMilliSeconds;
        public readonly int ExecutionRecurrences;
        int currentCommandIndex = 0;
        int currentRecurrence = 0;
        System.Timers.Timer _schedulingTimer;
        AutoResetEvent stopFlag;

        //CTOR with miliseconds use SchedulingIntervalInSeconds with x.0 or (double)
        public Scheduler(List<ICommand> Commands, double SchedulingIntervalInSeconds, int ExecutionRecurrences)
        {
            _commands = Commands;
            this.ExecutionRecurrences = ExecutionRecurrences;
            this.SchedulingIntervalInMilliSeconds = SchedulingIntervalInSeconds;
        }

        //CTOR with Minutes
        public Scheduler(List<ICommand> Commands, int SchedulingIntervalInMinutes, int ExecutionRecurrences)
            : this(Commands, ((double)SchedulingIntervalInMinutes * 60 * 1000), ExecutionRecurrences)
        {
        }

        public System.Collections.ObjectModel.ReadOnlyCollection<ICommand> Commands
        {
            get { return _commands.AsReadOnly(); }
        }

        public void Run()
        {
            //reset counter
            currentCommandIndex = 0;
            currentRecurrence = 0;
            stopFlag = new AutoResetEvent(false);
            _schedulingTimer = new System.Timers.Timer();
            //intervall is milliseconds 
            _schedulingTimer.Interval = SchedulingIntervalInMilliSeconds;
            _schedulingTimer.Elapsed += new ElapsedEventHandler(_schedulingTimer_Elapsed);
            _schedulingTimer.Enabled = true;
            //pause current thread here until scheduling is done
            stopFlag.WaitOne();
            //got signal from stopFlag so execution is finished
        }

        public bool IsFinished
        {
            get { return currentRecurrence == ExecutionRecurrences && currentCommandIndex == _commands.Count; }
        }

        void _schedulingTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            //multiple timer calls spawn multiple threads so we have to sync this
            //so only one thread should execute this code
            lock (sender)
            {
                //maybe antoher thread has finished execution and we were blocked so we our job is done
                if (!IsFinished)
                {
                    //avoid out of range
                    ICommand cmd = (currentCommandIndex >= _commands.Count ? null : _commands[currentCommandIndex]);
                    if (cmd != null)
                    {
                        cmd.Execute();
                        currentCommandIndex++;
                    }
                    //we have reached the last command in queue so reset command index
                    if (currentCommandIndex == _commands.Count)
                    {
                        currentRecurrence++;
                        //we´re finished all necessary runs
                        if (IsFinished)
                        {
                            _schedulingTimer.Enabled = false;
                            stopFlag.Set();
                        }
                        else
                        {
                            currentCommandIndex = 0;
                        }
                    }
                }
            }
        }
    }
}

Abgelegt unter scheduler, timer, reseteventflag.

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!