Exemplo n.º 1
0
        /// <summary>
        /// The dispatch loop run by each thread in the scheduler.
        /// </summary>
        private void DispatchLoop()
        {
            WorkStealingQueue <Task> workStealingQueue = new WorkStealingQueue <Task>();

            WorkStealingTaskScheduler.m_wsq = workStealingQueue;
            this.AddWsq(workStealingQueue);
            try
            {
                while (true)
                {
                    Task task = null;
                    if (!workStealingQueue.LocalPop(ref task))
                    {
                        bool flag = false;
                        while (true)
                        {
                            lock (this.m_queue)
                            {
                                if (this.m_shutdown)
                                {
                                    return;
                                }
                                if (this.m_queue.Count != 0)
                                {
                                    task = this.m_queue.Dequeue();
                                    break;
                                }
                                if (flag)
                                {
                                    this.m_threadsWaiting++;
                                    try
                                    {
                                        Monitor.Wait(this.m_queue);
                                    }
                                    finally
                                    {
                                        this.m_threadsWaiting--;
                                    }
                                    if (this.m_shutdown)
                                    {
                                        return;
                                    }
                                    flag = false;
                                    continue;
                                }
                            }
                            WorkStealingQueue <Task>[] wsQueues = this.m_wsQueues;
                            int i;
                            for (i = 0; i < wsQueues.Length; i++)
                            {
                                WorkStealingQueue <Task> workStealingQueue2 = wsQueues[i];
                                if (workStealingQueue2 != null && workStealingQueue2 != workStealingQueue && workStealingQueue2.TrySteal(ref task))
                                {
                                    break;
                                }
                            }
                            if (i != wsQueues.Length)
                            {
                                break;
                            }
                            flag = true;
                        }
                    }
                    base.TryExecuteTask(task);
                }
            }
            finally
            {
                this.RemoveWsq(workStealingQueue);
            }
        }
        /// <summary>
        /// The dispatch loop run by each thread in the scheduler.
        /// </summary>
        private void DispatchLoop()
        {
            // Create a new queue for this thread, store it in TLS for later retrieval,
            // and add it to the set of queues for this scheduler.
            WorkStealingQueue <Task> wsq = new WorkStealingQueue <Task>();

            m_wsq = wsq;
            AddWsq(wsq);

            try
            {
                // Until there's no more work to do...
                while (true)
                {
                    Task wi = null;

                    // Search order: (1) local WSQ, (2) global Q, (3) steals from other queues.
                    if (!wsq.LocalPop(ref wi))
                    {
                        // We weren't able to get a task from the local WSQ
                        bool searchedForSteals = false;
                        while (true)
                        {
                            lock (m_queue)
                            {
                                // If shutdown was requested, exit the thread.
                                if (m_shutdown)
                                {
                                    return;
                                }

                                // (2) try the global queue.
                                if (m_queue.Count != 0)
                                {
                                    // We found a work item! Grab it ...
                                    wi = m_queue.Dequeue();
                                    break;
                                }
                                else if (searchedForSteals)
                                {
                                    // Note that we're not waiting for work, and then wait
                                    m_threadsWaiting++;
                                    try { Monitor.Wait(m_queue); }
                                    finally { m_threadsWaiting--; }

                                    // If we were signaled due to shutdown, exit the thread.
                                    if (m_shutdown)
                                    {
                                        return;
                                    }

                                    searchedForSteals = false;
                                    continue;
                                }
                            }

                            // (3) try to steal.
                            WorkStealingQueue <Task>[] wsQueues = m_wsQueues;
                            int i;
                            for (i = 0; i < wsQueues.Length; i++)
                            {
                                WorkStealingQueue <Task> q = wsQueues[i];
                                if (q != null && q != wsq && q.TrySteal(ref wi))
                                {
                                    break;
                                }
                            }

                            if (i != wsQueues.Length)
                            {
                                break;
                            }

                            searchedForSteals = true;
                        }
                    }

                    // ...and Invoke it.
                    TryExecuteTask(wi);
                }
            }
            finally
            {
                RemoveWsq(wsq);
            }
        }