private static void PerformSmokeTest(int capacity, int parallelism, TimeSpan duration, Action payload)
        {
            var semaphore = new LifoSemaphore(capacity);

            var tasks = new List <Task>();

            var observedParallelism = 0;

            for (var i = 0; i < parallelism; i++)
            {
                tasks.Add(
                    Task.Run(
                        async() =>
                {
                    var watch = Stopwatch.StartNew();

                    while (watch.Elapsed < duration)
                    {
                        await semaphore.WaitAsync();

                        if (Interlocked.Increment(ref observedParallelism) > capacity)
                        {
                            throw new Exception($"Violated max allowed parallelism of {parallelism} (observed {observedParallelism})");
                        }

                        payload();

                        Interlocked.Decrement(ref observedParallelism);

                        semaphore.Release();
                    }
                }));
            }

            Task.WhenAll(tasks).GetAwaiter().GetResult();

            semaphore.CurrentCount.Should().Be(capacity);
            semaphore.CurrentQueue.Should().Be(0);

            Console.Out.WriteLine($"Success: capacity = {capacity}, parallelism = {parallelism}, duration = {duration}.");
        }
Ejemplo n.º 2
0
        public void Benchmark_multi_threaded_speed_vs_SemaphoreSlim(int capacity, int parallelism, int iterations)
        {
            var slimTimes = new List <double>();
            var lifoTimes = new List <double>();

            var slimSemaphore = new SemaphoreSlim(capacity, capacity);
            var lifoSemaphore = new LifoSemaphore(capacity);

            for (var i = 0; i < 5; i++)
            {
                var watch = Stopwatch.StartNew();

                var tasks = new List <Task>();

                for (var j = 0; j < parallelism; j++)
                {
                    tasks.Add(
                        Task.Run(
                            async() =>
                    {
                        for (var k = 0; k < iterations; k++)
                        {
                            await slimSemaphore.WaitAsync();

                            slimSemaphore.Release();
                        }
                    }));
                }

                Task.WhenAll(tasks).GetAwaiter().GetResult();

                slimTimes.Add(watch.Elapsed.TotalMilliseconds);

                Console.Out.WriteLine($"Slim: {watch.Elapsed.TotalMilliseconds:F2} ms");
            }

            var avgSlimTime = slimTimes.Average();

            Console.Out.WriteLine();
            Console.Out.WriteLine($"Slim avg: {avgSlimTime:F2} ms");
            Console.Out.WriteLine();

            for (var i = 0; i < 5; i++)
            {
                var watch = Stopwatch.StartNew();

                var tasks = new List <Task>();

                for (var j = 0; j < parallelism; j++)
                {
                    tasks.Add(
                        Task.Run(
                            async() =>
                    {
                        for (var k = 0; k < iterations; k++)
                        {
                            await lifoSemaphore.WaitAsync();

                            lifoSemaphore.Release();
                        }
                    }));
                }

                Task.WhenAll(tasks).GetAwaiter().GetResult();

                lifoTimes.Add(watch.Elapsed.TotalMilliseconds);

                Console.Out.WriteLine($"Lifo: {watch.Elapsed.TotalMilliseconds:F2} ms");
            }

            var avgLifoTime = lifoTimes.Average();

            Console.Out.WriteLine();
            Console.Out.WriteLine($"Lifo avg: {avgLifoTime:F2} ms");
            Console.Out.WriteLine();

            if (avgLifoTime < avgSlimTime)
            {
                Console.Out.WriteLine($"Winner is LifoSemaphore ({avgSlimTime / avgLifoTime:F2}x)!");
                Assert.Pass();
            }
            else
            {
                Console.Out.WriteLine($"Winner is SemaphoreSlim ({avgLifoTime / avgSlimTime:F2}x)!");
                Assert.Inconclusive();
            }
        }
Ejemplo n.º 3
0
 public void WaitAsync_should_return_completed_tasks_immediately_until_count_goes_negative()
 {
     semaphore.WaitAsync().IsCompleted.Should().BeTrue();
     semaphore.WaitAsync().IsCompleted.Should().BeTrue();
     semaphore.WaitAsync().IsCompleted.Should().BeTrue();
 }
Ejemplo n.º 4
0
 public void Lifo()
 {
     lifoSemaphore.WaitAsync().GetAwaiter().GetResult();
     lifoSemaphore.Release();
 }