public void SetMaximumWorkerThreadsCountShouldAddNoWorkerThreadsToReachTheMaximumThreadCountWhenMaximumThreadsCountIncreasesAndThereAreWorkItemsInTheQueue()
        {
            ManualFinishWorkItemQueueStub manualFinishWorkItemQueueStub = new ManualFinishWorkItemQueueStub();

            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());
            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());

            WorkerThreadPool workerThreadPool = new WorkerThreadPool(manualFinishWorkItemQueueStub, 1, 2);

            manualFinishWorkItemQueueStub.WaitAllStart(500);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workerThreadPool.QueueWorkItem(new ManualFinishWorkItem());
            workerThreadPool.QueueWorkItem(new ManualFinishWorkItem());

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            Assert.AreEqual(2, manualFinishWorkItemQueueStub.Count);

            workerThreadPool.SetMaximumWorkerThreadsCount(4);

            manualFinishWorkItemQueueStub.WaitAllStart(500);

            Assert.AreEqual(4, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(4, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            Assert.AreEqual(0, manualFinishWorkItemQueueStub.Count);

            manualFinishWorkItemQueueStub.StopAll();

            workerThreadPool.Shutdown(true, 500);
        }
        public void QueueWorkItemShouldAddANewWorkerThreadWhenMaxThreadCountIsNotReached()
        {
            ManualFinishWorkItemQueueStub workItemQueue = new ManualFinishWorkItemQueueStub();

            workItemQueue.Enqueue(new ManualFinishWorkItem());

            WorkerThreadPool workerThreadPool = new WorkerThreadPool(workItemQueue, 0, 2);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);

            workItemQueue.WaitAllStart(500);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);

            ManualFinishWorkItem newWorkItem = new ManualFinishWorkItem();

            workerThreadPool.QueueWorkItem(newWorkItem);
            newWorkItem.WaitStart(500);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workItemQueue.StopAll();

            workerThreadPool.Shutdown(true, 500);
        }
        public void WorkerThreadIdleTimeOutTest()
        {
            WorkerThreadPool workerThreadPool = new WorkerThreadPool(800, 2, 4);

            // İş parçası süresi / İş parçası eklenme süresi = 400 / 100 => 4 İşçi Thread gerekli.
            int   workItemDuration = 400;
            Timer timer            = new Timer(100);

            timer.AutoReset = true;
            timer.Elapsed  += (sender, args) =>
            {
                workerThreadPool.QueueWorkItem(
                    new ActionWorkItem(
                        () =>
                {
                    Thread.Sleep(workItemDuration);
                }));
            };
            timer.Start();

            Thread.Sleep(3000);

            Assert.AreEqual(4, workerThreadPool.WorkerThreadsCount);

            // İş parçası süresi / İş parçası eklenme süresi = 150 / 100 => 2 İşçi Thread gerekli.
            Interlocked.Add(ref workItemDuration, -250); // 400 - 250 = 150

            Thread.Sleep(3000);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);

            timer.Stop();

            workerThreadPool.Shutdown(true, 3000);
        }
        public void QueueWorkItemShouldThrowExceptionWhenWorkerThreadPoolIsShutDown()
        {
            WorkerThreadPool workerThreadPool = new WorkerThreadPool();

            workerThreadPool.Shutdown();

            Assert.Throws <LaboThreadingException>(() => workerThreadPool.QueueWorkItem(Substitute.For <IWorkItem>()));
        }
        public void A()
        {
            Random           random           = new Random();
            WorkerThreadPool workerThreadPool = new WorkerThreadPool(6 * 10 * 1000, 8, 8);
            const int        workItemsCount   = 100;
            int counter = 0;
            int totalSleepMilliseconds = 0;

            IList <IWorkItem> workItems = new List <IWorkItem>(workItemsCount);

            for (int i = 0; i < workItemsCount; i++)
            {
                ActionWorkItem workItem = new ActionWorkItem(
                    () =>
                {
                    int sleepMilliseconds = random.Next(1000, 2000);
                    Interlocked.Add(ref totalSleepMilliseconds, sleepMilliseconds);
                    Thread.Sleep(sleepMilliseconds);
                    Interlocked.Increment(ref counter);
                });
                workItems.Add(workItem);
            }

            Stopwatch stopwatch = Stopwatch.StartNew();

            stopwatch.Start();

            for (int i = 0; i < workItems.Count; i++)
            {
                IWorkItem workItem = workItems[i];
                workerThreadPool.QueueWorkItem(workItem);
            }

            workerThreadPool.Shutdown(true, 500);

            stopwatch.Stop();

            TimeSpan totalExecutionTime = TimeSpan.Zero;

            for (int i = 0; i < workItems.Count; i++)
            {
                IWorkItem workItem = workItems[i];
                totalExecutionTime += workItem.ExecutionTime;
            }

            totalExecutionTime.ToString();
        }
        public void A()
        {
            Random random = new Random();
            WorkerThreadPool workerThreadPool = new WorkerThreadPool(6 * 10 * 1000, 8, 8);
            const int workItemsCount = 100;
            int counter = 0;
            int totalSleepMilliseconds = 0;
            
            IList<IWorkItem> workItems = new List<IWorkItem>(workItemsCount);
            for (int i = 0; i < workItemsCount; i++)
            {
                ActionWorkItem workItem = new ActionWorkItem(
                    () =>
                        {
                            int sleepMilliseconds = random.Next(1000, 2000);
                            Interlocked.Add(ref totalSleepMilliseconds, sleepMilliseconds);
                            Thread.Sleep(sleepMilliseconds);
                            Interlocked.Increment(ref counter);
                        });
                workItems.Add(workItem);                
            }

            Stopwatch stopwatch = Stopwatch.StartNew();
            stopwatch.Start();

            for (int i = 0; i < workItems.Count; i++)
            {
                IWorkItem workItem = workItems[i];
                workerThreadPool.QueueWorkItem(workItem);
            }

            workerThreadPool.Shutdown(true, 500);

            stopwatch.Stop();

            TimeSpan totalExecutionTime = TimeSpan.Zero;
            for (int i = 0; i < workItems.Count; i++)
            {
                IWorkItem workItem = workItems[i];
                totalExecutionTime += workItem.ExecutionTime;
            }

            totalExecutionTime.ToString();
        }
        public void QueueWorkItemShouldThrowExceptionWhenWorkItemIsNull()
        {
            WorkerThreadPool workerThreadPool = new WorkerThreadPool();

            Assert.Throws <ArgumentNullException>(() => workerThreadPool.QueueWorkItem(null));
        }
 public void QueueWorkItemShouldThrowExceptionWhenWorkItemIsNull()
 {
     WorkerThreadPool workerThreadPool = new WorkerThreadPool();
     Assert.Throws<ArgumentNullException>(() => workerThreadPool.QueueWorkItem(null));
 }
        public void QueueWorkItemShouldThrowExceptionWhenWorkerThreadPoolIsShutDown()
        {
            WorkerThreadPool workerThreadPool = new WorkerThreadPool();
            workerThreadPool.Shutdown();

            Assert.Throws<LaboThreadingException>(() => workerThreadPool.QueueWorkItem(Substitute.For<IWorkItem>()));
        }
        public void QueueWorkItemShouldAddANewWorkerThreadWhenMaxThreadCountIsNotReached()
        {
            ManualFinishWorkItemQueueStub workItemQueue = new ManualFinishWorkItemQueueStub();
            workItemQueue.Enqueue(new ManualFinishWorkItem());

            WorkerThreadPool workerThreadPool = new WorkerThreadPool(workItemQueue, 0, 2);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);

            workItemQueue.WaitAllStart(500);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);

            ManualFinishWorkItem newWorkItem = new ManualFinishWorkItem();
            workerThreadPool.QueueWorkItem(newWorkItem);
            newWorkItem.WaitStart(500);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workItemQueue.StopAll();

            workerThreadPool.Shutdown(true, 500);
        }
        public void WorkerThreadIdleTimeOutTest()
        {
            WorkerThreadPool workerThreadPool = new WorkerThreadPool(800, 2, 4);
            
            // İş parçası süresi / İş parçası eklenme süresi = 400 / 100 => 4 İşçi Thread gerekli.
            int workItemDuration = 400;
            Timer timer = new Timer(100);
            timer.AutoReset = true;
            timer.Elapsed += (sender, args) =>
                {
                    workerThreadPool.QueueWorkItem(
                        new ActionWorkItem(
                            () =>
                                {
                                    Thread.Sleep(workItemDuration);
                                }));
                };
            timer.Start();

            Thread.Sleep(3000);

            Assert.AreEqual(4, workerThreadPool.WorkerThreadsCount);

            // İş parçası süresi / İş parçası eklenme süresi = 150 / 100 => 2 İşçi Thread gerekli.
            Interlocked.Add(ref workItemDuration, -250); // 400 - 250 = 150

            Thread.Sleep(3000);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);

            timer.Stop();

            workerThreadPool.Shutdown(true, 3000);
        }
        public void SetMaximumWorkerThreadsCountShouldAddNoWorkerThreadsToReachTheMaximumThreadCountWhenMaximumThreadsCountIncreasesAndThereAreWorkItemsInTheQueue()
        {
            ManualFinishWorkItemQueueStub manualFinishWorkItemQueueStub = new ManualFinishWorkItemQueueStub();
            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());
            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());

            WorkerThreadPool workerThreadPool = new WorkerThreadPool(manualFinishWorkItemQueueStub, 1, 2);

            manualFinishWorkItemQueueStub.WaitAllStart(500);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workerThreadPool.QueueWorkItem(new ManualFinishWorkItem());
            workerThreadPool.QueueWorkItem(new ManualFinishWorkItem());

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            Assert.AreEqual(2, manualFinishWorkItemQueueStub.Count);

            workerThreadPool.SetMaximumWorkerThreadsCount(4);

            manualFinishWorkItemQueueStub.WaitAllStart(500);

            Assert.AreEqual(4, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(4, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            Assert.AreEqual(0, manualFinishWorkItemQueueStub.Count);

            manualFinishWorkItemQueueStub.StopAll();

            workerThreadPool.Shutdown(true, 500);
        }