/// <summary>
        ///     This is called by the worker thread when it finishes it's current job. It adds the worker thread back into the
        ///     queue of available threads.
        /// </summary>
        /// <param name="sender"> This should always be a reference to the GenericThread that has finished. </param>
        /// <param name="e"> Nothing interesting in here. </param>
        private void JobFinished(object sender, EventArgs e)
        {
            Debug.Assert(sender is GenericThread);
            GenericThread gt = (GenericThread)sender;
            // Add the thread back into the 'free' list.

            int busyListCount;

            lock (_threadBusyListLock)
            {
                bool c**k = _threadBusyList.Remove(gt);
                Debug.Assert(c**k == true);
                busyListCount = _threadBusyList.Count;

                // If we're ending the last thread, the threads are now idle.
                if (busyListCount == 0)
                {
                    this.ThreadsAreIdle.Set();
                }

                // Keep this outside of any lock.
                OnThreadBusyCountChangedEvent(busyListCount + 1, busyListCount);
            }
            // This is a ThreadSafe queue so we don't need to lock before Enqueueing.
            _threadAvailableList.Enqueue(gt);
        }
Пример #2
0
        /// <summary>
        ///     If the job queue is not empty and there is an available worker thread then the next job is sent to the worker thread.
        /// </summary>
        private void PokeTheQueue()
        {
            if (_bSuspendQueue == false)
            {
                int oldQueueSize, newQueueSize;
                lock (_jobQueue)
                {
                    oldQueueSize = _jobQueue.Count;
                    if (_jobQueue.Count > 0)
                    {
                        lock (_threadAvailableList)
                        {
                            // Use a 'while' rather than an 'if' because although this function is called each time a job is queued
                            // and each time a worker thread becomes available and there therefore the worker threads should always
                            // be saturated, if the queue is suspended then jobs aren't picked out of the queue when threads become available.
                            while (_threadAvailableList.Count > 0 && _jobQueue.Count > 0)
                            {
                                GenericThread genericThread = _threadAvailableList.Dequeue();
                                lock (_threadBusyList)
                                {
                                    _threadBusyList.Add(genericThread);
                                }
                                Job nextJob = _jobQueue.Dequeue().WrappedJob;
                                //Debug.WriteLine("Starting Job named '"+nextJob.Name+"'. Queue Size: " + _jobQueue.Count);

                                genericThread.StartJob(nextJob);
                            }
                        }
                    }
                    newQueueSize = _jobQueue.Count;
                }
                if (oldQueueSize != newQueueSize)                // Keep this outside of the lock.
                {
                    OnThreadManagerQueueSizeChangedEvent(_jobQueue.Count + 1, _jobQueue.Count);
                }
            }
        }