コード例 #1
0
            public void Should_block_wait_thread_while_not_relese_enough_counter()
            {
                var limiter = new Limiter(0, 10);

                var waitTasks = new []
                {
                    new Task(() => limiter.WaitFree(), TaskCreationOptions.LongRunning),
                    new Task(() => limiter.WaitFree(), TaskCreationOptions.LongRunning),
                    new Task(() => limiter.WaitFree(), TaskCreationOptions.LongRunning)
                };

                Start(waitTasks);
                var whenAll = Task.WhenAll(waitTasks);
                var whenAny = Task.WhenAny(waitTasks);

                whenAll.Wait(200);
                whenAll.IsCompleted.Should().BeFalse();

                limiter.TryRelease(out _);

                whenAny.Wait(100);
                whenAny.IsCompleted.Should().BeTrue();
                whenAll.IsCompleted.Should().BeFalse();

                limiter.TryRelease(2, out _);
                whenAll.Wait(100);
                whenAll.IsCompleted.Should().BeTrue();

                limiter.CurrentFreeNumber.Should().Be(0);
            }
コード例 #2
0
            private void ReleaseFor(Limiter limiter, int times, int?step = null)
            {
                var released = 0;
                var i        = 0;

                while (released < times)
                {
                    int currentTimes;

                    if (step.HasValue)
                    {
                        currentTimes = step.Value;
                    }
                    else
                    {
                        currentTimes = i++ % 3 + 1;
                        if (currentTimes + released > times)
                        {
                            currentTimes = 1;
                        }
                    }

                    if (limiter.TryRelease(currentTimes, out _))
                    {
                        released += currentTimes;
                    }
                }
            }
コード例 #3
0
            public void Should_return_true_when_is_have_free_numbers()
            {
                var limiter = new Limiter(10);

                var result = limiter.TryRelease(5, out _);

                result.Should().BeTrue();
            }
コード例 #4
0
            public void Should_return_old_value(int count, int release, int expectedValue)
            {
                var limiter = new Limiter(count);

                limiter.TryRelease(release, out var oldValue);

                oldValue.Should().Be(expectedValue);
            }
コード例 #5
0
            public void Should_throw_when_try_to_release_invalid_number(int value)
            {
                var limiter = new Limiter(10);

                Action action = () => limiter.TryRelease(value, out _);

                action.Should().Throw <ArgumentException>();
            }
コード例 #6
0
            public void Should_not_release_when_given_count_more_than_have_free()
            {
                var limiter = new Limiter(10, 11);

                limiter.TryRelease(5, out _);

                limiter.CurrentFreeNumber.Should().Be(10);
            }
コード例 #7
0
            public void Should_return_current_value_when_given_count_more_than_have_free()
            {
                var limiter = new Limiter(10, 11);

                limiter.TryRelease(5, out var current);

                current.Should().Be(10);
            }
コード例 #8
0
            public void Should_return_false_when_given_count_more_than_have_free()
            {
                var limiter = new Limiter(10, 11);

                var result = limiter.TryRelease(5, out _);

                result.Should().BeFalse();
            }
コード例 #9
0
            public void Should_increase_current_value()
            {
                var limiter = new Limiter(10);

                limiter.TryRelease(5, out _);

                limiter.CurrentFreeNumber.Should().Be(15);
            }
コード例 #10
0
            public void Should_wait_and_release_by_some_number_from_different_threads()
            {
                var limiter = new Limiter(0, 10, log);

                var waitTask = new Task(
                    () =>
                {
                    for (var i = 0; i < 100; i++)
                    {
                        limiter.WaitFree();
                    }
                },
                    TaskCreationOptions.LongRunning);

                var releaseTask = new Task(
                    () =>
                {
                    var released = 100;
                    var i        = 0;
                    while (released > 0)
                    {
                        var times = i++ % 3 + 1;
                        if (limiter.TryRelease(times, out _))
                        {
                            released -= times;
                        }
                        Thread.SpinWait(times * 3);
                    }
                },
                    TaskCreationOptions.LongRunning);

                Start(waitTask, releaseTask);
                var whenAll = Task.WhenAll(waitTask, releaseTask);

                whenAll.Wait(200);

                whenAll.IsCompleted.Should().BeTrue();

                limiter.CurrentFreeNumber.Should().BeLessOrEqualTo(10);
            }