public Task StopAsync(QueueStopReason reason = null) { stopReason = reason = reason ?? defaultStopReason; stopped = new TaskCompletionSource <object>(); Dispatch(_ => { foreach (var queue in queues.Where(x => reason.IsCancellable(this, x.Type))) { queue.Cancel(); } }); return(stopped.Task); }
private void Process() { // Each iteration here we'll call a round while (true) { // Process any requests that have come in that want to perform blocking work on the processor thread. ProcessDispatches(); var wasItemDequeued = false; foreach (var queue in queues) { if (queue.IsAvailable && (!queue.cancellationToken.IsCancellationRequested || stopReason.IsCancellable(this, queue.Type))) { var queueItem = queue.Dequeue(); wasItemDequeued = true; queue.Activate(queueItem); Task.Run(() => queueItem.Execute().ContinueWith(_ => Dispatch(processor => queue.Deactivate(queueItem)))); } else { queue.MarkWaiting(); } } if (!wasItemDequeued && !dispatches.Any()) { if (stopReason != null) { break; } if (queues.All(x => x.IsIdle)) { Log("All queues idle, triggering idle task"); idled.SetResult(null); idled = new TaskCompletionSource <object>(); } // Wait for either a new item to be enqueued (waiter) or for the cancellation token to be triggered Log("Round finished, waiting"); waiting.SetResult(null); waiting = new TaskCompletionSource <object>(); waiter.WaitOne(); } } Debug.Assert(stopped != null); stopReason = null; stopped.SetResult(null); }