Exemple #1
0
        private void ThreadProc(ThreadPrivateData privateData, CancellationToken token)
        {
            if (privateData == null)
            {
                throw new InvalidOperationException("privateData for Thread of ThreadPool can't be null");
            }


            ThreadPoolWorkItem currentWorkItem = null;

            try
            {
                while (!token.IsCancellationRequested && !ShouldIDie())
                {
                    if (this.TryTakeWorkItemFromQueue(privateData, out currentWorkItem, Timeout.Infinite, token, false))
                    {
                        this.RunWorkItem(currentWorkItem);
                        currentWorkItem = null;

                        if (_wasSomeProcessByThreadsFlag == false)
                        {
                            _wasSomeProcessByThreadsFlag = true;
                        }
                    }
                    else
                    {
                        TurboContract.Assert(token.IsCancellationRequested, conditionString: "token.IsCancellationRequested");
                    }
                }
            }
            catch (OperationCanceledException)
            {
                if (!token.IsCancellationRequested)
                {
                    throw;
                }
            }


            if (token.IsCancellationRequested)
            {
                if (LetFinishedProcess)
                {
                    while (this.TryTakeWorkItemFromQueue(privateData, out currentWorkItem))
                    {
                        this.RunWorkItem(currentWorkItem);
                    }
                }
                else
                {
                    while (this.TryTakeWorkItemFromQueue(privateData, out currentWorkItem))
                    {
                        this.CancelWorkItem(currentWorkItem);
                    }
                }
            }
        }
        private void UniversalThreadProc(ThreadPrivateData privateData, CancellationToken token)
        {
            if (privateData == null)
            {
                throw new InvalidOperationException("privateData for Thread of ThreadPool can't be null");
            }


            ThreadPoolWorkItem currentWorkItem = null;
            int lastViewedActiveThreadCount    = 0;

            try
            {
                while (!token.IsCancellationRequested)
                {
                    if (!_extThreadBlocker.Wait(_noWorkItemTrimPeriod, token))
                    {
                        if (RequestDieSlot(_minThreadCount))
                        {
                            //Console.WriteLine("Thread exit due to staying deactivated");
                            break;
                        }
                        // Иначе активируемся
                        ActivateThread();
                    }

                    bool itemTaken = this.TryTakeWorkItemFromQueue(privateData, out currentWorkItem, 0, new CancellationToken(), false);
                    if (itemTaken == false)
                    {
                        lastViewedActiveThreadCount = this.ActiveThreadCount;
                        // this.ActiveThreadCount <= _reasonableThreadCount - возможна гонка, но нам не критично
                        if (lastViewedActiveThreadCount <= _reasonableThreadCount)
                        {
                            itemTaken = this.TryTakeWorkItemFromQueue(privateData, out currentWorkItem, _noWorkItemTrimPeriod, token, false);
                        }
                        else
                        {
                            itemTaken = this.TryTakeWorkItemFromQueue(privateData, out currentWorkItem, NoWorkItemPreventDeactivationPeriod, token, false);
                        }
                    }

                    if (itemTaken)
                    {
                        this.RunWorkItem(currentWorkItem);
                        currentWorkItem = null;

                        _throughoutTracker.RegisterExecution();
                        if (_wasSomeProcessByThreadsFlag == false)
                        {
                            _wasSomeProcessByThreadsFlag = true;
                        }
                    }
                    else if (!token.IsCancellationRequested)
                    {
                        if (lastViewedActiveThreadCount <= _reasonableThreadCount)
                        {
                            if (this.PrimaryThreadCount > _fastSpawnThreadCountLimit)
                            {
                                DeactivateThread(_fastSpawnThreadCountLimit);
                            }
                            else
                            {
                                DeactivateThread(_minThreadCount);
                            }
                        }
                        else
                        {
                            DeactivateThread(_reasonableThreadCount);
                        }

                        //Console.WriteLine("Thread self deactivation due to empty queue");
                    }
                }
            }
            catch (OperationCanceledException)
            {
                if (!token.IsCancellationRequested)
                {
                    throw;
                }
            }


            if (token.IsCancellationRequested)
            {
                if (LetFinishedProcess)
                {
                    while (this.TryTakeWorkItemFromQueue(privateData, out currentWorkItem))
                    {
                        this.RunWorkItem(currentWorkItem);
                    }
                }
                else
                {
                    while (this.TryTakeWorkItemFromQueue(privateData, out currentWorkItem))
                    {
                        this.CancelWorkItem(currentWorkItem);
                    }
                }
            }
        }