public void MinThreads_Throws_ArgumentException_When_Zero()
 {
     var target = new ThreadPoolSettings()
     {
         MinThreads = 0,
     };
 }
 public void MinThreads_Throws_ArgumentException_When_Negative()
 {
     var target = new ThreadPoolSettings()
     {
         MinThreads = -1,
     };
 }
 public void NewSettings_object_contains_DefaultValues()
 {
     ThreadPoolSettings target = new ThreadPoolSettings();
     Assert.AreEqual(target.MinThreads, 1); //default min threads are always 1
     Assert.AreEqual(target.MaxThreads, Environment.ProcessorCount); //default max threads are always 1
     Assert.AreEqual(target.ThreadIdleTimeout,
         new TimeSpan(0, 0, 0, 0, TheadPoolDefaultLimits.DefaultThreadIdleTimeout));
 }
 public void MinThreads_Throws_ArgumentOutOfRangeException_When_GreaterThanMaxThreads()
 {
     var target = new ThreadPoolSettings()
     {
         MaxThreads=10,
         MinThreads = 20,
     };
 }
        public void Ensure_CancelToken_StopsThreadPool()
        {
            bool itemprocessed = false;
            //Arrange
            var settings = new ThreadPoolSettings()
            {
                MaxThreads = 2,
                MinThreads = 1,
                ThreadIdleTimeout = new TimeSpan(0, 0, 0, 0, 10), //10 ms thread idle timeout
            };
            using (var tokenSrc = new CancellationTokenSource())
            {
                using (var pool = new CustomThreadPool3(settings, tokenSrc.Token))
                {
                    var queued = pool.QueueUserWorkItem((c, o) =>
                    {
                        itemprocessed = true; //indicates the item is processed by the pool.

                    }, null);

                    Assert.IsTrue(queued);

                    Assert.AreEqual(1, pool.TotalThreads);

                    //Act
                    //send cancel request to the pool
                    tokenSrc.Cancel();
                    //try to enqueue another item
                    queued = pool.QueueUserWorkItem((c, o) =>
                    {
                        itemprocessed = true; //indicates the item is processed by the pool.

                    }, null);

                    //Assert
                    Assert.IsFalse(queued); //after cancel, user cant queue new work
                }
            }
        }
        public void Ensure_ThreadPool_Shrinks_To_MinimumThreads()
        {
            //Arrange
            var settings = new ThreadPoolSettings()
            {
                MaxThreads = 3,
                MinThreads = 1,
                ThreadIdleTimeout = new TimeSpan(0, 0, 0, 0, 1), //1 ms thread idle timeout,
                NewThreadWaitTime = TimeSpan.FromMilliseconds(1),
            };

            //Act
            using (var pool = new CustomThreadPool2(settings, CancellationToken.None))
            {
                //Act
                for (int i = 0; i < 10000; i++)
                {
                    pool.QueueUserWorkItem((c, o) =>
                    {
                        //Thread.Sleep(1);
                    }, null);

                }

                //Assert
                Assert.AreEqual(3, pool.TotalThreads); //ensure reached to max limit
                //now wait for 100 ms that ensures all items are processed
                Thread.Sleep(1000);
                //ensure pool reached to min size now
                Assert.AreEqual(1, pool.TotalThreads);
            }
        }
        public void Ensure_ThreadPool_Runs_MinimumThreads()
        {
            //Arrange
            var settings = new ThreadPoolSettings()
            {
                MaxThreads = 100,
                MinThreads = 10,
                ThreadIdleTimeout = new TimeSpan(0, 0, 0, 0, 10), //10 ms thread idle timeout
            };

            //Act
            using (var pool = new CustomThreadPool2(settings, CancellationToken.None))
            {
                //Assert
                Assert.AreEqual(10, pool.TotalThreads);
                //wait for 100ms and ensure pool still runs 10 threads
                Thread.Sleep(15);
                //Assert
                Assert.AreEqual(10, pool.TotalThreads);
            }
        }
        public void Ensure_ThreadPool_Runs_MaximumThreads()
        {
            //Arrange
            var settings = new ThreadPoolSettings()
            {
                MaxThreads = 2,
                MinThreads = 1,
                ThreadIdleTimeout = new TimeSpan(0, 0, 0, 0, 5000), //5 sec. thread idle timeout
            };

            //Act
            using (var pool = new CustomThreadPool2(settings, CancellationToken.None))
            {
                //Act
                for (int i = 0; i < 10; i++)
                {
                    pool.QueueUserWorkItem((c, o) =>
                    {
                        Thread.Sleep(1);
                    }, null);

                }

                //Assert
                Assert.AreEqual(2, pool.TotalThreads);
            }
        }
        public void Ensure_ThreadPool_Shrinks_To_MinimumThreads()
        {
            //Arrange
            var settings = new ThreadPoolSettings()
            {
                MaxThreads = 3,
                MinThreads = 1,
                ThreadIdleTimeout = new TimeSpan(0, 0, 0, 0, 100), //1 ms thread idle timeout
                NewThreadWaitTime = TimeSpan.FromMilliseconds(0),
            };

            //Act
            using (var pool = new CustomThreadPool1(settings, CancellationToken.None))
            {
                //Act
                for (int i = 0; i < 10000; i++)
                {
                    pool.QueueUserWorkItem((c, o) =>
                    {
                        //Thread.Sleep(1);
                    }, null);

                }

                //Assert
                Assert.AreEqual(settings.MaxThreads, pool.TotalThreads); //ensure reached to max limit
                Thread.Sleep(3000);
                Assert.IsTrue(pool.TotalThreads < settings.MaxThreads);
            }
        }
        public void Ensure_ThreadPool_Shrinks_To_MinimumThreads()
        {
            //Arrange
            var settings = new ThreadPoolSettings()
            {
                MaxThreads = 4,
                MinThreads = 1,
                ThreadIdleTimeout = new TimeSpan(0, 0, 0, 0, 5), //5 ms thread idle timeout
                NewThreadWaitTime = TimeSpan.FromMilliseconds(0),
            };

            //Act
            using (var pool = new CustomThreadPool3(settings, CancellationToken.None))
            {
                //Act
                for (int i = 0; i < 100000; i++)
                {
                    pool.QueueUserWorkItem((c, o) =>
                    {
                        //Thread.Sleep(0);
                    }, null);

                }
                //Assert
                Assert.AreEqual(4, pool.TotalThreads); //ensure reached to max limit
               //wait till all threads are drained
                while (pool.TotalThreads > settings.MinThreads)
                {
                    //Console.WriteLine(pool.TotalThreads);
                    Thread.Sleep(10);
                }
                //ensure pool reached to min size now
                Assert.AreEqual(1, pool.TotalThreads);
            }
        }