/// <summary> /// Process tasks one at a time in the best order. /// This should be run in a Task generated by QueueTask. /// It's been separated out into its own method to show up better in Parallel Tasks. /// </summary> private void ProcessPrioritizedAndBatchedTasks() { bool continueProcessing = true; while (!_disposeCancellation.IsCancellationRequested && continueProcessing) { try { // Until there are no more tasks to process while (!_disposeCancellation.IsCancellationRequested) { // Try to get the next task. If there aren't any more, we're done. Task targetTask; lock (_nonthreadsafeTaskQueue) { if (_nonthreadsafeTaskQueue.Count == 0) { break; } targetTask = _nonthreadsafeTaskQueue.Dequeue(); } // If the task is null, it's a placeholder for a task in the round-robin queues. // Find the next one that should be processed. QueuedTaskSchedulerQueue queueForTargetTask = null; if (targetTask == null) { lock (_queueGroups) FindNextTask_NeedsLock(out targetTask, out queueForTargetTask); } // Now if we finally have a task, run it. If the task // was associated with one of the round-robin schedulers, we need to use it // as a thunk to execute its task. if (targetTask != null) { if (queueForTargetTask != null) { queueForTargetTask.ExecuteTask(targetTask); } else { TryExecuteTask(targetTask); } } } } finally { // Now that we think we're done, verify that there really is // no more work to do. If there's not, highlight // that we're now less parallel than we were a moment ago. lock (_nonthreadsafeTaskQueue) { if (_nonthreadsafeTaskQueue.Count == 0) { _delegatesQueuedOrRunning--; continueProcessing = false; } } } } }
/// <summary> /// Process tasks one at a time in the best order. /// This should be run in a Task generated by QueueTask. /// It's been separated out into its own method to show up better in Parallel Tasks. /// </summary> private void ProcessPrioritizedAndBatchedTasks() { bool flag = true; while (!this._disposeCancellation.IsCancellationRequested && flag) { try { _taskProcessingThread.Value = true; while (!this._disposeCancellation.IsCancellationRequested) { Task task; lock (this._nonthreadsafeTaskQueue) { if (this._nonthreadsafeTaskQueue.Count == 0) { break; } task = this._nonthreadsafeTaskQueue.Dequeue(); } QueuedTaskSchedulerQueue queueForTargetTask = null; if (task == null) { lock (this._queueGroups) { this.FindNextTask_NeedsLock(out task, out queueForTargetTask); } } if (task != null) { if (queueForTargetTask != null) { queueForTargetTask.ExecuteTask(task); } else { base.TryExecuteTask(task); } } } continue; } finally { lock (this._nonthreadsafeTaskQueue) { if (this._nonthreadsafeTaskQueue.Count == 0) { this._delegatesQueuedOrRunning--; flag = false; _taskProcessingThread.Value = false; } } } } }