Implementing a Scheduler(something that implements a given schedule) I am trying to implement a class that implements a given schedule. I am trying to design this Scheduler class so it can be paused and everything. I have just written some example code so I can better convey my requirements. I would be grateful if more experienced minds could take a look and tell me if what I have right now is the right way to go about things or if there are better ways to do this. I'd really appreciate some thoughts.

class Scheduler {

    private object locker = new object();
    private System.Timers.Timer timer = new System.Timers.Timer();
    private int[] schedule = null;
    private int scheduleIndex = 0;
    private bool offline = true;
    private bool timerElapsed;

    private Thread th;

    public Scheduler() {
        timer.Elapsed += new System.Timers.ElapsedEventHandler(TimerElapsedHandler);
        th = new Thread(RunSchedule);
        th.Start();
    }

    public void RunSchedule() {
        lock (locker) {
            while (schedule == null || scheduleIndex &gt; schedule.length) // this will not throw a NullReferenceException since schedule == null is being checked first
                Monitor.Wait(locker);

            while (offline)
                Monitor.Wait(locker);

            // pick up next schedule and start timer and wait till timer finishes
            int nextSchedule = schedule[scheduleIndex];

            // call external program to execute schedule

            timer.Interval = 120 * 1000;
            timerElapsed = false;
            timer.Start();
            while(!timerElapsed)
                Monitor.Wait(locker);
        }
    }

    public void Offline() {
        lock (locker) {
            // pause thread executing RunThread
            offline = true;
            // also kill timer if running
            if (timer.Enabled) {
                timer.Stop();
                timerElapsed = true;
                Monitor.Pulse(locker);
            }
        }

    }

    public void Online() {
        lock (locker) {
            //Pulse thread executing RunThread
            offline = false;
            Monitor.Pulse(locker);
        }
    }

    public void OfflineTooLong() {
        lock(locker) {
            this.schedule = null;
        }
    }

    public void ScheduleReady(int[] schedule) {
        lock (locker) {
            this.schedule = schedule;
            this.scheduleIndex = 0;
            Monitor.Pulse(locker);
        }
    }

    private void TimerElapsedHandler(object sender, System.Timers.ElapsedEventArgs) {
        lock(locker) {
            scheduleIndex++;
            timerElapsed = true;
            Monitor.Pulse(locker);
        }
    }
}


As you can see from the code, the intent is to "pause" the thread implementing the schedule when Offline and restart the thread when Online. Also, if you've run through all schedules(ie either schedule == null because you've been Offline too long or scheduleIndex &gt; schedule.length), it should wait to receive a new schedule.

Any thoughts and help will be much appreciated.
Your code is super-comlicated for such simple logic. I'm also pretty sure it deadlocks in pretty much any use case.

class Scheduler : IDisposable
{
    private readonly object scheduleLock = new object();
    private int[] schedule = null;
    private int scheduleIndex = 0;
    private readonly ManualResetEvent collectionResetEvent = new ManualResetEvent(false);
    private readonly AutoResetEvent delayEvent = new AutoResetEvent(false);
    private volatile bool working;

    private Thread th;

    public Dispose()
    {
        Offline();
    }

    public void RunSchedule() 
    {
        while (true)
        {
            collectionResetEvent.WaitOne();
            if (!working) return;

            lock (scheduleLock)
            {
               if (schedule == null || scheduleIndex &gt;= shedule.Count) 
               {
                   collectionResetEvent.Reset();
                   if (!working) return;
               }
               else
               {
                   var nextSchedule = schedule[scheduleIndex++];
                   //execute, 
                   //probably can be done outside the lock
               }
            }

            delayEvent.WaitOne(120 * 1000);
        }
    }

    public void Offline() 
    {
        if (!working) return;
        working = false;
        delayEvent.Set();
        collectionResetEvent.Set();
        th.Join();
        th = null;
    }

    public void Online() 
    {
        if (working) return;
        working = true;
        th = new Thread(RunSchedule);
        th.Start();
    }

    public void OfflineTooLong() 
    {
        ScheduleReady(null);
    }

    public void ScheduleReady(int[] schedule) 
    {
        lock (scheduleLock) 
        {
            schedule = schedule;
            scheduleIndex = 0;
            collectionResetEvent.Set();
            delayEvent.Set();
        }
    }
}


This is just an example of how it can be refactored, to give you an idea. It can still potentially deadlock (for example if you call offline and dispose at the same time from different threads) so it requires some tweaking depending on your requirements. RunSchedule() method is somewhat hard to read, it should be splitted into sub-methods. BartoszKP makes a perfectly valid points as well, check his answer, if you haven't already.