예제 #1
0
        public async Task IncreaseConcurrency()
        {
            int count = 0;

            var waitForFirstTwoItems = TaskSourceSlim.Create <object>();
            // Event that will hold first two workers.
            var mre         = new ManualResetEventSlim(false);
            var actionBlock = new ActionBlockSlim <int>(
                2,
                n =>
            {
                var currentCount = Interlocked.Increment(ref count);
                if (currentCount == 2)
                {
                    // Notify the test that 2 items are processed.
                    waitForFirstTwoItems.SetResult(null);
                }

                if (currentCount <= 2)
                {
                    // This is the first or the second thread that should be blocked before we increase the number of threads.
                    mre.Wait(TimeSpan.FromSeconds(100));
                }

                Thread.Sleep(1);
            });

            // Schedule work
            actionBlock.Post(1);
            actionBlock.Post(2);

            await waitForFirstTwoItems.Task;

            // The first 2 threads should be blocked in the callback in the action block,
            // but the count should be incremented
            Assert.Equal(2, count);

            var task = actionBlock.CompletionAsync();

            // The task should not be completed yet!
            Assert.NotEqual(TaskStatus.RanToCompletion, task.Status);

            // This will cause another thread to spawn
            actionBlock.IncreaseConcurrencyTo(3);

            // Add more work
            actionBlock.Post(3);

            actionBlock.Complete();

            // Release the first 2 threads
            mre.Set();

            // Waiting for completion
            await task;

            // The new thread should run and increment the count
            Assert.Equal(3, count);
        }
        /// <summary>
        /// Changes the concurrency level.
        /// </summary>
        public void IncreaseConcurrencyTo(int maxDegreeOfParallelism)
        {
            Contract.Requires(maxDegreeOfParallelism >= -1);

            maxDegreeOfParallelism = maxDegreeOfParallelism == -1 ? Environment.ProcessorCount : maxDegreeOfParallelism;
            if (maxDegreeOfParallelism > m_serializationQueue.DegreeOfParallelism)
            {
                m_serializationQueue.IncreaseConcurrencyTo(maxDegreeOfParallelism);
            }
        }