Exemple #1
0
        /// <summary>Find the next task that should be executed, based on priorities and fairness and the like.</summary>
        /// <param name="targetTask">The found task, or null if none was found.</param>
        /// <param name="queueForTargetTask">
        /// The scheduler associated with the found task.  Due to security checks inside of TPL,
        /// this scheduler needs to be used to execute that task.
        /// </param>
        private void FindNextTask_NeedsLock(out Task targetTask, out QueuedTaskSchedulerQueue queueForTargetTask)
        {
            targetTask         = null;
            queueForTargetTask = null;

            // Look through each of our queue groups in sorted order.
            // This ordering is based on the priority of the queues.
            foreach (var queueGroup in _queueGroups)
            {
                var queues = queueGroup.Value;

                // Within each group, iterate through the queues in a round-robin
                // fashion.  Every time we iterate again and successfully find a task,
                // we'll start in the next location in the group.
                foreach (int i in queues.CreateSearchOrder())
                {
                    queueForTargetTask = queues[i];
                    var items = queueForTargetTask._workItems;
                    if (items.Count > 0)
                    {
                        targetTask = items.Dequeue();
                        if (queueForTargetTask._disposed && items.Count == 0)
                        {
                            RemoveQueue_NeedsLock(queueForTargetTask);
                        }
                        queues.NextQueueIndex = (queues.NextQueueIndex + 1) % queueGroup.Value.Count;
                        return;
                    }
                }
            }
        }
Exemple #2
0
 /// <summary>Initializes the debug view.</summary>
 /// <param name="queue">The queue to be debugged.</param>
 public QueuedTaskSchedulerQueueDebugView(QueuedTaskSchedulerQueue queue)
 {
     if (queue == null)
     {
         throw new ArgumentNullException("queue");
     }
     _queue = queue;
 }
        /// <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;
                        }
                    }
                }
            }
        }
Exemple #4
0
        /// <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;
                        }
                    }
                }
            }
        }
Exemple #5
0
        /// <summary>Removes a scheduler from the group.</summary>
        /// <param name="queue">The scheduler to be removed.</param>
        private void RemoveQueue_NeedsLock(QueuedTaskSchedulerQueue queue)
        {
            QueueGroup group = this._queueGroups[queue._priority];
            int        index = group.IndexOf(queue);

            if (group.NextQueueIndex >= index)
            {
                group.NextQueueIndex--;
            }
            group.RemoveAt(index);
        }
Exemple #6
0
        /// <summary>Removes a scheduler from the group.</summary>
        /// <param name="queue">The scheduler to be removed.</param>
        private void RemoveQueue_NeedsLock(QueuedTaskSchedulerQueue queue)
        {
            // Find the group that contains the queue and the queue's index within the group
            var queueGroup = _queueGroups[queue._priority];
            int index      = queueGroup.IndexOf(queue);

            // We're about to remove the queue, so adjust the index of the next
            // round-robin starting location if it'll be affected by the removal
            if (queueGroup.NextQueueIndex >= index)
            {
                queueGroup.NextQueueIndex--;
            }

            // Remove it
            queueGroup.RemoveAt(index);
        }
Exemple #7
0
        /// <summary>Creates and activates a new scheduling queue for this scheduler.</summary>
        /// <param name="priority">The priority level for the new queue.</param>
        /// <returns>The newly created and activated queue at the specified priority.</returns>
        public TaskScheduler ActivateNewQueue(int priority)
        {
            QueuedTaskSchedulerQueue item = new QueuedTaskSchedulerQueue(priority, this);

            lock (this._queueGroups)
            {
                QueueGroup group;
                if (!this._queueGroups.TryGetValue(priority, out group))
                {
                    group = new QueueGroup();
                    this._queueGroups.Add(priority, group);
                }
                group.Add(item);
            }
            return(item);
        }
Exemple #8
0
        /// <summary>Creates and activates a new scheduling queue for this scheduler.</summary>
        /// <param name="priority">The priority level for the new queue.</param>
        /// <returns>The newly created and activated queue at the specified priority.</returns>
        public TaskScheduler ActivateNewQueue(int priority)
        {
            // Create the queue
            var createdQueue = new QueuedTaskSchedulerQueue(priority, this);

            // Add the queue to the appropriate queue group based on priority
            lock (_queueGroups)
            {
                if (!_queueGroups.TryGetValue(priority, out QueueGroup list))
                {
                    list = new QueueGroup();
                    _queueGroups.Add(priority, list);
                }
                list.Add(createdQueue);
            }

            // Hand the new queue back
            return(createdQueue);
        }
Exemple #9
0
 /// <summary>Find the next task that should be executed, based on priorities and fairness and the like.</summary>
 /// <param name="targetTask">The found task, or null if none was found.</param>
 /// <param name="queueForTargetTask">
 /// The scheduler associated with the found task.  Due to security checks inside of TPL,
 /// this scheduler needs to be used to execute that task.
 /// </param>
 private void FindNextTask_NeedsLock(out Task targetTask, out QueuedTaskSchedulerQueue queueForTargetTask)
 {
     targetTask         = null;
     queueForTargetTask = null;
     foreach (KeyValuePair <int, QueueGroup> pair in this._queueGroups)
     {
         QueueGroup group = pair.Value;
         foreach (int num in group.CreateSearchOrder())
         {
             queueForTargetTask = group[num];
             Queue <Task> queue = queueForTargetTask._workItems;
             if (queue.Count > 0)
             {
                 targetTask = queue.Dequeue();
                 if (queueForTargetTask._disposed && (queue.Count == 0))
                 {
                     this.RemoveQueue_NeedsLock(queueForTargetTask);
                 }
                 group.NextQueueIndex = (group.NextQueueIndex + 1) % pair.Value.Count;
                 break;
             }
         }
     }
 }
 /// <summary>Initializes the debug view.</summary>
 /// <param name="queue">The queue to be debugged.</param>
 public QueuedTaskSchedulerQueueDebugView(QueuedTaskSchedulerQueue queue)
 {
     _queue = queue ?? throw new ArgumentNullException("queue");
 }
 public QueuedTaskSchedulerQueueDebugView(QueuedTaskSchedulerQueue queue) => _Queue = queue ?? throw new ArgumentNullException(nameof(queue));
 /// <summary>Initializes the debug view.</summary>
 /// <param name="queue">The queue to be debugged.</param>
 public QueuedTaskSchedulerQueueDebugView(QueuedTaskSchedulerQueue queue) =>