Nito.AsyncEx.Context/AsyncContext.TaskScheduler.cs
using System.Collections.Generic; using System.Threading.Tasks; namespace Nito.AsyncEx { public sealed partial class AsyncContext { /// <summary> /// A task scheduler which schedules tasks to an async context. /// </summary> private sealed class AsyncContextTaskScheduler : TaskScheduler { /// <summary> /// The async context for this task scheduler. /// </summary> private readonly AsyncContext _context; /// <summary> /// Initializes a new instance of the <see cref="AsyncContextTaskScheduler"/> class. /// </summary> /// <param name="context">The async context for this task scheduler. May not be <c>null</c>.</param> public AsyncContextTaskScheduler(AsyncContext context) { _context = context; } /// <summary> /// Generates an enumerable of <see cref="Task"/> instances currently queued to the scheduler waiting to be executed. /// </summary> /// <returns>An enumerable that allows traversal of tasks currently queued to this scheduler.</returns> [System.Diagnostics.DebuggerNonUserCode] protected override IEnumerable<Task> GetScheduledTasks() { return _context._queue.GetScheduledTasks(); } /// <summary> /// Queues a <see cref="Task"/> to the scheduler. If all tasks have been completed and the outstanding asynchronous operation count is zero, then this method has undefined behavior. /// </summary> /// <param name="task">The <see cref="Task"/> to be queued.</param> protected override void QueueTask(Task task) { _context.Enqueue(task, false); } /// <summary> /// Determines whether the provided <see cref="Task"/> can be executed synchronously in this call, and if it can, executes it. /// </summary> /// <param name="task">The <see cref="Task"/> to be executed.</param> /// <param name="taskWasPreviouslyQueued">A Boolean denoting whether or not task has previously been queued. If this parameter is True, then the task may have been previously queued (scheduled); if False, then the task is known not to have been queued, and this call is being made in order to execute the task inline without queuing it.</param> /// <returns>A Boolean value indicating whether the task was executed inline.</returns> /// <exception cref="System.InvalidOperationException">The <paramref name="task"/> was already executed.</exception> protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) { return (AsyncContext.Current == _context) && TryExecuteTask(task); } /// <summary> /// Indicates the maximum concurrency level this <see cref="TaskScheduler"/> is able to support. /// </summary> public override int MaximumConcurrencyLevel { get { return 1; } } /// <summary> /// Exposes the base <see cref="TaskScheduler.TryExecuteTask"/> method. /// </summary> /// <param name="task">The task to attempt to execute.</param> public void DoTryExecuteTask(Task task) { TryExecuteTask(task); } } } } |