/// <summary>Queues a task to the scheduler.</summary>
        /// <param name="task">The task to be scheduled.</param>
        protected override void QueueTask(Task task)
        {
            // Make sure the pool is started, e.g. that all threads have been created.
            m_threads.Force();

            // If the task is marked as long-running, give it its own dedicated thread
            // rather than queueing it.
            if ((task.CreationOptions & TaskCreationOptions.LongRunning) != 0)
            {
                new Thread(state => base.TryExecuteTask((Task)state))
                {
                    IsBackground = true
                }.Start(task);
            }
            else
            {
                // Otherwise, insert the work item into a queue, possibly waking a thread.
                // If there's a local queue and the task does not prefer to be in the global queue,
                // add it to the local queue.
                WorkStealingQueue <Task> wsq = m_wsq;
                if (wsq != null && ((task.CreationOptions & TaskCreationOptions.PreferFairness) == 0))
                {
                    // Add to the local queue and notify any waiting threads that work is available.
                    // Races may occur which result in missed event notifications, but they're benign in that
                    // this thread will eventually pick up the work item anyway, as will other threads when another
                    // work item notification is received.
                    wsq.LocalPush(task);
                    if (m_threadsWaiting > 0) // OK to read lock-free.
                    {
                        lock (m_queue) { Monitor.Pulse(m_queue); }
                    }
                }
                // Otherwise, add the work item to the global queue
                else
                {
                    lock (m_queue)
                    {
                        m_queue.Enqueue(task);
                        if (m_threadsWaiting > 0)
                        {
                            Monitor.Pulse(m_queue);
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>Queues a task to the scheduler.</summary>
        /// <param name="task">The task to be scheduled.</param>
        protected override void QueueTask(Task task)
        {
            this.m_threads.Force <Thread[]>();
            if ((task.CreationOptions & TaskCreationOptions.LongRunning) != TaskCreationOptions.None)
            {
                new Thread(delegate(object state)
                {
                    base.TryExecuteTask((Task)state);
                })
                {
                    IsBackground = true
                }.Start(task);
                return;
            }
            WorkStealingQueue <Task> wsq = WorkStealingTaskScheduler.m_wsq;

            if (wsq != null && (task.CreationOptions & TaskCreationOptions.PreferFairness) == TaskCreationOptions.None)
            {
                wsq.LocalPush(task);
                if (this.m_threadsWaiting <= 0)
                {
                    return;
                }
                lock (this.m_queue)
                {
                    Monitor.Pulse(this.m_queue);
                    return;
                }
            }
            lock (this.m_queue)
            {
                this.m_queue.Enqueue(task);
                if (this.m_threadsWaiting > 0)
                {
                    Monitor.Pulse(this.m_queue);
                }
            }
        }