public void Schedule(Action <object> action, object state, TimeSpan delay, CancellationToken cancellationToken) { var queueNode = new ScheduledTaskQueueNode(action, state, PreciseTimeSpan.Deadline(delay), cancellationToken); if (this.InEventLoop) { this.scheduledTaskQueue.Enqueue(queueNode); } else { this.Execute(e => ((SingleThreadEventExecutor)e).scheduledTaskQueue.Enqueue(queueNode), this); // it is an allocation but it should not happen often (cross-thread scheduling) } }
void FetchFromScheduledTaskQueue() { if (this.HasScheduledTasks()) { PreciseTimeSpan nanoTime = PreciseTimeSpan.FromStart; while (true) { ScheduledTaskQueueNode scheduledTask = this.PollScheduledTask(nanoTime); if (scheduledTask == null) { break; } this.taskQueue.Enqueue(scheduledTask); this.semaphore.Release(); } } }
ScheduledTaskQueueNode PollScheduledTask(PreciseTimeSpan nanoTime) { Debug.Assert(this.InEventLoop); ScheduledTaskQueueNode scheduledTask = this.scheduledTaskQueue.Peek(); if (scheduledTask == null) { return(null); } if (scheduledTask.Deadline <= nanoTime) { this.scheduledTaskQueue.Dequeue(); return(scheduledTask); } return(null); }
public int CompareTo(ScheduledTaskQueueNode other) { Contract.Requires(other != null); return(this.Deadline.CompareTo(other.Deadline)); }
bool HasScheduledTasks() { ScheduledTaskQueueNode scheduledTask = this.scheduledTaskQueue.Peek(); return(scheduledTask != null && scheduledTask.Deadline <= PreciseTimeSpan.FromStart); }