/// <summary> /// Run this Timers event loop in its own Thread. /// </summary> public void Run() { while (true) { TimerTask task; lock (this.syncRoot) { // need to check cancelled inside the synchronized block if (cancelled) { return; } if (tasks.IsEmpty()) { if (finished) { return; } // no tasks scheduled -- sleep until any task appear try { Monitor.Wait(this.syncRoot); } catch (ThreadInterruptedException) { } continue; } DateTime currentTime = DateTime.Now; task = tasks.Minimum(); TimeSpan timeToSleep; lock (task.syncRoot) { if (task.cancelled) { tasks.Delete(0); continue; } // check the time to sleep for the first task scheduled timeToSleep = task.when - currentTime; } if (timeToSleep.CompareTo(TimeSpan.Zero) > 0) { // sleep! try { Monitor.Wait(this.syncRoot, timeToSleep); } catch (ThreadInterruptedException) { } continue; } // no sleep is necessary before launching the task lock (task.syncRoot) { int pos = 0; if (tasks.Minimum().when != task.when) { pos = tasks.GetTask(task); } if (task.cancelled) { tasks.Delete(tasks.GetTask(task)); continue; } // set time to schedule task.ScheduledTime = task.when; // remove task from queue tasks.Delete(pos); // set when the next task should be launched if (task.period.CompareTo(TimeSpan.Zero) >= 0) { // this is a repeating task, if (task.fixedRate) { // task is scheduled at fixed rate task.when = task.when + task.period; } else { // task is scheduled at fixed delay task.when = DateTime.Now + task.period; } // insert this task into queue InsertTask(task); } else { task.when = DateTime.MinValue; } } } bool taskCompletedNormally = false; try { task.Run(); taskCompletedNormally = true; } finally { if (!taskCompletedNormally) { lock (this) { cancelled = true; } } } } }