/// <remarks> /// Get the first task, if the running time hasn't been /// reached then wait a bit and retry. Else reschedule the task and then /// run it. /// </remarks> /// <summary> /// If the task queue is empty, sleep until a task comes in or if slept /// for too long, suspend the thread. /// </summary> private void _run() { long elapsedTime; long interval; try { while (true) { lock (this) { if (thread == null) { return; } } Task task = null; bool lockReAcquired = true; lock (queue) { if (queue.IsEmpty) { lockReAcquired = Monitor.Wait(queue, (int)suspend_interval); } if (lockReAcquired) { QueuedEvent e = queue.Peek(); if (e != null) { lock (e) { interval = e.Interval; task = e.Task; if (task.IsCancelled()) { queue.Pop(); continue; } elapsedTime = e.ElapsedTime; if (elapsedTime >= interval) { // Reschedule the task queue.Pop(); if (e.ReQueue()) { queue.Push(e); } } } if (elapsedTime < e.Interval) { Monitor.Wait(queue, (int)(e.Interval - elapsedTime)); continue; } } } } lock (this) { if (queue.IsEmpty && !lockReAcquired) { _suspend(); return; } } try { if (task != null) { if (_concurrent) { ThreadPool.QueueUserWorkItem(ExecuterCallback, task); } else { task.Run(); } } } catch (Exception ex) { Trace.error("TimeScheduler._run()", ex.ToString()); } } } catch (ThreadInterruptedException ex) { Trace.error("TimeScheduler._run()", ex.ToString()); } }
/// <remarks> /// Get the first task, if the running time hasn't been /// reached then wait a bit and retry. Else reschedule the task and then /// run it. /// </remarks> /// <summary> /// If the task queue is empty, sleep until a task comes in or if slept /// for too long, suspend the thread. /// </summary> private void _run() { long elapsedTime; long interval; try { while (true) { lock (this) { if (thread == null) { return; } } Task task = null; bool lockReAcquired = true; lock (queue) { if (queue.IsEmpty) { lockReAcquired = Monitor.Wait(queue, (int)suspend_interval); } if (lockReAcquired) { QueuedEvent e = queue.Peek(); if (e != null) { lock (e) { task = e.Task; if (task.IsCancelled()) { queue.Pop(); continue; } elapsedTime = e.ElapsedTime; interval = e.Interval; if (elapsedTime >= interval) { // Reschedule the task queue.Pop(); if (e.ReQueue()) { queue.Push(e); } } } if (elapsedTime < interval) { // argument out of range exception, might be fixed with this check.. hopefully if (interval - elapsedTime > 0) { if ((interval - elapsedTime) > Int32.MaxValue) { Monitor.Wait(queue, Int32.MaxValue); } else { Monitor.Wait(queue, (int)(interval - elapsedTime)); } } continue; } } } } lock (this) { if (queue.IsEmpty && !lockReAcquired) { _suspend(); return; } } try { if (task != null && task.Enabled) { task.Run(); } } catch (Exception ex) { Trace.error("TimeScheduler._run()", ex.ToString()); } } } catch (ThreadInterruptedException ex) { Trace.error("TimeScheduler._run()", ex.ToString()); } }