public bool TryTakeItem(ThreadPoolThreadLocals local, bool doLocalSearch, bool doWorkSteal, out ThreadPoolWorkItem item, int timeout, CancellationToken token, bool throwOnCancellation)
        {
            Contract.Ensures(Contract.Result <bool>() == false || Contract.ValueAtReturn(out item) != null);
            Debug.Assert(!_isDisposed);

            if (local != null)
            {
                return(_queues.TryTake(local.LocalQueue, doLocalSearch, doWorkSteal, out item, timeout, token, throwOnCancellation));
            }
            else
            {
                return(_queues.TryTake(null, doLocalSearch, doWorkSteal, out item, timeout, token, throwOnCancellation));
            }
        }
        public bool TryTakeItem(ThreadPoolThreadLocals local, out ThreadPoolWorkItem item)
        {
            Contract.Ensures(Contract.Result <bool>() == false || Contract.ValueAtReturn(out item) != null);
            Debug.Assert(!_isDisposed);

            if (local != null)
            {
                return(_queues.TryTake(local.LocalQueue, out item, 0, new CancellationToken(), true));
            }
            else
            {
                return(_queues.TryTake(null, out item, 0, new CancellationToken(), true));
            }
        }
        public ThreadPoolWorkItem TakeItem(ThreadPoolThreadLocals local, CancellationToken token)
        {
            Contract.Ensures(Contract.Result <ThreadPoolWorkItem>() != null);
            Debug.Assert(!_isDisposed);

            if (local != null)
            {
                return(_queues.Take(local.LocalQueue, token));
            }
            else
            {
                return(_queues.Take(null, token));
            }
        }
        public ThreadPoolWorkItem TakeItem(ThreadPoolThreadLocals local, CancellationToken token)
        {
            TurboContract.Ensures(TurboContract.Result <ThreadPoolWorkItem>() != null);
            TurboContract.Assert(!_isDisposed, conditionString: "!_isDisposed");

            if (local != null)
            {
                return(_queues.Take(local.LocalQueue, token));
            }
            else
            {
                return(_queues.Take(null, token));
            }
        }
        public bool TryAddItem(ThreadPoolWorkItem item, bool forceGlobal)
        {
            Contract.Requires(item != null);
            Debug.Assert(!_isDisposed);

            ThreadPoolLocalQueue localQueue = null;

            if (!forceGlobal)
            {
                ThreadPoolThreadLocals threadLocal = _perThreadData.Value;
                localQueue = threadLocal != null ? threadLocal.LocalQueue : null;
            }

            return(_queues.TryAdd(item, localQueue, forceGlobal));
        }
        public bool TryAddItem(ThreadPoolWorkItem item, bool forceGlobal)
        {
            TurboContract.Requires(item != null, conditionString: "item != null");
            TurboContract.Assert(!_isDisposed, conditionString: "!_isDisposed");

            ThreadPoolLocalQueue localQueue = null;

            if (!forceGlobal)
            {
                ThreadPoolThreadLocals threadLocal = _perThreadData.Value;
                localQueue = threadLocal != null ? threadLocal.LocalQueue : null;
            }

            return(_queues.TryAdd(item, localQueue, forceGlobal));
        }
        /// <summary>
        /// Получить или создать данные для текущего потока.
        /// Предполагается, что вызывающий поток принадлежит пулу потоков
        /// </summary>
        /// <param name="createThreadLocalQueue">Создавать ли локальную очередь потока</param>
        /// <returns>Данные потока</returns>
        public ThreadPoolThreadLocals GetOrCreateThisThreadData(bool createThreadLocalQueue = true)
        {
            Contract.Ensures(Contract.Result <ThreadPoolThreadLocals>() != null);
            Debug.Assert(!_isDisposed);

            ThreadPoolThreadLocals result = _perThreadData.Value;

            if (result == null)
            {
                result = new ThreadPoolThreadLocals(this, createThreadLocalQueue);
                _perThreadData.Value = result;
                if (createThreadLocalQueue)
                {
                    _queues.AddLocalQueue(result.LocalQueue);
                }
            }

            return(result);
        }
        /// <summary>
        /// Удалить локальные данные текущего потока
        /// </summary>
        public void FreeThisThreadData()
        {
            ThreadPoolThreadLocals data = _perThreadData.Value;

            if (data == null)
            {
                return;
            }
            if (data.LocalQueue != null)
            {
                _queues.RemoveLocalQueue(data.LocalQueue);
            }
            _perThreadData.Value = null;

            if (data.LocalQueue != null)
            {
                _queues.MoveItemsFromLocalQueueToGlobal(data.LocalQueue);
            }
            data.Dispose();
        }