/// <summary> /// Add a task which will be run after a specified delay. /// </summary> /// <param name="task">The work to be done.</param> /// <param name="timeUntilRun">Milliseconds until run.</param> /// <param name="repeat">Whether this task should repeat.</param> public ScheduledDelegate AddDelayed(Action task, double timeUntilRun, bool repeat = false) { ScheduledDelegate del = new ScheduledDelegate(task, timer.ElapsedMilliseconds + timeUntilRun, repeat ? timeUntilRun : -1); return(Add(del) ? del : null); }
/// <summary> /// Run any pending work tasks. /// </summary> /// <returns>true if any tasks were run.</returns> public virtual int Update() { lock (timedTasks) { double currentTimeLocal = currentTime; if (timedTasks.Count > 0) { foreach (var sd in timedTasks) { if (sd.ExecutionTime <= currentTimeLocal) { tasksToRemove.Add(sd); if (sd.Cancelled) { continue; } runQueue.Enqueue(sd); if (sd.RepeatInterval >= 0) { if (timedTasks.Count > 1000) { throw new ArgumentException("Too many timed tasks are in the queue!"); } sd.ExecutionTime += sd.RepeatInterval; tasksToSchedule.Add(sd); } } } foreach (var t in tasksToRemove) { timedTasks.Remove(t); } tasksToRemove.Clear(); foreach (var t in tasksToSchedule) { timedTasks.AddInPlace(t); } tasksToSchedule.Clear(); } } for (int i = 0; i < perUpdateTasks.Count; i++) { ScheduledDelegate task = perUpdateTasks[i]; if (task.Cancelled) { perUpdateTasks.RemoveAt(i--); continue; } runQueue.Enqueue(task); } int countToRun = runQueue.Count; int countRun = 0; while (runQueue.TryDequeue(out ScheduledDelegate sd)) { if (sd.Cancelled) { continue; } //todo: error handling sd.RunTask(); if (++countRun == countToRun) { break; } } return(countRun); }
/// <summary> /// Run any pending work tasks. /// </summary> /// <returns>true if any tasks were run.</returns> public int Update() { //purge any waiting timed tasks to the main schedulerQueue. lock (timedTasks) { long currentTime = timer.ElapsedMilliseconds; ScheduledDelegate sd; while (timedTasks.Count > 0 && (sd = timedTasks[0]).WaitTime <= currentTime) { timedTasks.RemoveAt(0); if (sd.Cancelled) { continue; } schedulerQueue.Enqueue(sd.RunTask); if (sd.RepeatInterval > 0) { if (timedTasks.Count < 1000) { sd.WaitTime += sd.RepeatInterval; } // This should never ever happen... but if it does, let's not overflow on queued tasks. else { Debug.Print("Timed tasks are overflowing. Can not keep up with periodic tasks."); sd.WaitTime = timer.ElapsedMilliseconds + sd.RepeatInterval; } timedTasks.AddInPlace(sd); } } for (int i = 0; i < perUpdateTasks.Count; i++) { ScheduledDelegate task = perUpdateTasks[i]; if (task.Cancelled) { perUpdateTasks.RemoveAt(i--); continue; } schedulerQueue.Enqueue(task.RunTask); } } int countRun = 0; Action action; while (schedulerQueue.TryDequeue(out action)) { //todo: error handling action.Invoke(); countRun++; } return(countRun); }
/// <summary> /// Run any pending work tasks. /// </summary> /// <returns>true if any tasks were run.</returns> public int Update() { long currentTime = timer.ElapsedMilliseconds; lock (timedTasks) { if (timedTasks.Count > 0) { foreach (var sd in timedTasks) { if (sd.ExecutionTime <= currentTime) { tasksToRemove.Add(sd); if (sd.Cancelled) { break; } schedulerQueue.Enqueue(sd.RunTask); if (sd.RepeatInterval >= 0) { if (timedTasks.Count > 1000) { throw new OverflowException("Too many timed tasks are in the queue!"); } sd.ExecutionTime += sd.RepeatInterval; tasksToSchedule.Add(sd); } } } foreach (var t in tasksToRemove) { timedTasks.Remove(t); } tasksToRemove.Clear(); foreach (var t in tasksToSchedule) { timedTasks.AddInPlace(t); } tasksToSchedule.Clear(); } } for (int i = 0; i < perUpdateTasks.Count; i++) { ScheduledDelegate task = perUpdateTasks[i]; if (task.Cancelled) { perUpdateTasks.RemoveAt(i--); continue; } schedulerQueue.Enqueue(task.RunTask); } int countRun = 0; Action action; while (schedulerQueue.TryDequeue(out action)) { //todo: error handling action.Invoke(); countRun++; } return(countRun); }
/// <summary> /// Run any pending work tasks. /// </summary> /// <returns>true if any tasks were run.</returns> public void Update() { Action[] runnable; lock (schedulerQueue) { //purge any waiting timed tasks to the main schedulerQueue. lock (timedTasks) { long currentTime = timer.ElapsedMilliseconds; ScheduledDelegate sd; while (timedTasks.Count > 0 && (sd = timedTasks[0]).WaitTime <= currentTime) { timedTasks.RemoveAt(0); if (sd.Cancelled) { continue; } schedulerQueue.Enqueue(sd.RunTask); if (sd.RepeatInterval > 0) { if (timedTasks.Count < 1000) { sd.WaitTime += sd.RepeatInterval; } // This should never ever happen... but if it does, let's not overflow on queued tasks. else { Debug.Print("Timed tasks are overflowing. Can not keep up with periodic tasks."); sd.WaitTime = timer.ElapsedMilliseconds + sd.RepeatInterval; } timedTasks.AddInPlace(sd); } } for (int i = 0; i < perUpdateTasks.Count; i++) { ScheduledDelegate task = perUpdateTasks[i]; if (task.Cancelled) { perUpdateTasks.RemoveAt(i--); continue; } schedulerQueue.Enqueue(task.RunTask); } } int c = schedulerQueue.Count; if (c == 0) { return; } //create a safe copy of pending tasks. runnable = new Action[c]; schedulerQueue.CopyTo(runnable, 0); schedulerQueue.Clear(); } foreach (Action v in runnable) { //todo: error handling v.Invoke(); } }
public virtual bool Add(ScheduledDelegate task) { lock (timedTasks) timedTasks.AddInPlace(task); return(true); }