public void TestMinFreeElementChanging()
        {
            UsedElementTracker testInst = new UsedElementTracker(1000);

            Assert.AreEqual(int.MaxValue, testInst.MinFreeElementsCount);

            testInst.UpdateMinFreeElementCount(100);
            Assert.AreEqual(100, testInst.MinFreeElementsCount);

            testInst.UpdateMinFreeElementCount(200);
            Assert.AreEqual(100, testInst.MinFreeElementsCount);

            testInst.UpdateMinFreeElementCount(1);
            Assert.AreEqual(1, testInst.MinFreeElementsCount);
        }
        public void TestResetWorks()
        {
            UsedElementTracker testInst = new UsedElementTracker(1000);

            Assert.AreEqual(int.MaxValue, testInst.MinFreeElementsCount);

            testInst.UpdateMinFreeElementCount(100);
            Assert.AreEqual(100, testInst.MinFreeElementsCount);

            testInst.Reset();
            Assert.AreEqual(int.MaxValue, testInst.MinFreeElementsCount);
        }
        public void TestItemFixationWorks()
        {
            UsedElementTracker testInst = new UsedElementTracker(10);

            Assert.AreEqual(int.MaxValue, testInst.MinFreeElementsCount);

            testInst.UpdateMinFreeElementCount(100);
            Assert.AreEqual(100, testInst.MinFreeElementsCount);

            Thread.Sleep(100);
            testInst.UpdateState();

            Assert.AreEqual(100, testInst.ElementToDestroy);
            Assert.AreEqual(int.MaxValue, testInst.MinFreeElementsCount);
        }
        public void TestElementToDestroyDecrements()
        {
            UsedElementTracker testInst = new UsedElementTracker(10);

            testInst.UpdateMinFreeElementCount(100);
            Thread.Sleep(100);
            testInst.UpdateState();


            Assert.AreEqual(100, testInst.ElementToDestroy);
            Assert.AreEqual(int.MaxValue, testInst.MinFreeElementsCount);

            for (int i = 0; i < 100; i++)
            {
                Assert.IsTrue(testInst.RequestElementToDestroy());
                Assert.AreEqual(100 - i - 1, testInst.ElementToDestroy);
            }

            Assert.IsFalse(testInst.RequestElementToDestroy());
        }
Beispiel #5
0
        /// <summary>
        /// Rents element from pool
        /// </summary>
        /// <param name="timeout">Waiting timeout in milliseconds (-1 - infinity)</param>
        /// <param name="token">Token to cancel waiting for element availability</param>
        /// <param name="throwOnUnavail">True - throws <see cref="CantRetrieveElementException"/> when element can't be rented, otherwise returns null</param>
        /// <returns>Wrapper for rented element</returns>
        protected sealed override PoolElementWrapper <TElem> RentElement(int timeout, System.Threading.CancellationToken token, bool throwOnUnavail)
        {
            if (_disposeCancellation.IsCancellationRequested)
            {
                if (throwOnUnavail)
                {
                    throw new CantRetrieveElementException("Rent from pool failed. Dispose was called.", new ObjectDisposedException(this.GetType().Name));
                }

                return(null);
            }

            if (token.IsCancellationRequested)
            {
                if (throwOnUnavail)
                {
                    token.ThrowIfCancellationRequested();
                }

                return(null);
            }


            if (timeout < 0)
            {
                timeout = Timeout.Infinite;
            }

            PoolElementWrapper <TElem> result            = null;
            CancellationTokenSource    linkedTokenSource = null;

            try
            {
                result = TryGetElement(0, new CancellationToken());

                if (result == null && timeout != 0)
                {
                    if (!token.CanBeCanceled)
                    {
                        result = TryGetElement(timeout, _disposeCancellation.Token);
                    }
                    else
                    {
                        linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token, _disposeCancellation.Token);
                        result            = TryGetElement(timeout, linkedTokenSource.Token);
                    }
                }
            }
            catch (OperationCanceledException)
            {
            }
            finally
            {
                if (linkedTokenSource != null)
                {
                    linkedTokenSource.Dispose();
                }
            }


            // Обновление числа занятых элементов (для удаления неиспользуемых)
            _usedElementTracker.UpdateMinFreeElementCount(this.FreeElementCount);


            if (throwOnUnavail && result == null)
            {
                if (_disposeCancellation.IsCancellationRequested)
                {
                    // We should attempt to destroy element that was potentially occupied for small amout of time
                    this.TakeDestroyAndRemoveElement();
                    if (_elementsContainer.Count == 0)
                    {
                        _stoppedEvent.Set();
                    }

                    throw new CantRetrieveElementException("Rent from pool failed. Dispose was called.", new ObjectDisposedException(this.GetType().Name));
                }

                token.ThrowIfCancellationRequested();

                if (timeout >= 0)
                {
                    throw new TimeoutException(string.Format("Pool 'Rent' operation has timeouted. Pool: {0}. Timeout value: {1}ms", this.Name, timeout));
                }

                TurboContract.Assert(false, "Element in pool is not available. Reason: UNKNOWN!");
                throw new CantRetrieveElementException("Rent from pool failed");
            }


            Profiling.Profiler.ObjectPoolElementRented(this.Name, this.RentedElementCount);
            return(result);
        }