/// <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); } } } } }
/// <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); } } }