Esempio n. 1
0
        public void CancelLockAsync_Cancel()
        {
            // setup
            var semaphore = new SemaphoreSlim(1);
            var value     = new List();
            var subject   = new AsyncSynchronized <List>(semaphore, value);

            // act and assert
            Should.Throw <TaskCanceledException>(() => subject.LockAsync(new CancellationTokenSource(0).Token));
        }
Esempio n. 2
0
        public void CancelWithLockAsyncAction_Cancel()
        {
            // setup
            var semaphore = new SemaphoreSlim(1);
            var value     = new List();
            var subject   = new AsyncSynchronized <List>(semaphore, value);

            // act and assert
            Should.Throw <TaskCanceledException>(() => subject.WithLockAsync((v) => Task.FromResult(0), new CancellationTokenSource(0).Token));

            semaphore.CurrentCount.ShouldBe(1);
        }
Esempio n. 3
0
        public async Task BarelyLockAsync_Acquire()
        {
            // setup
            var semaphore = new SemaphoreSlim(1);
            var value     = new List();
            var subject   = new AsyncSynchronized <List>(semaphore, value);

            // act and assert
            var result = await subject.BarelyLockAsync();

            semaphore.CurrentCount.ShouldBe(0);
            result.ShouldBe(value);
        }
Esempio n. 4
0
        public void WithLockAsyncFunc_Exception_Release()
        {
            // setup
            var semaphore = new SemaphoreSlim(1);
            var value     = new List();
            var subject   = new AsyncSynchronized <List>(semaphore, value);

            // act and assert
            Should.Throw <CustomException>(() => subject.WithLockAsync(new Func <List, int>((v) =>
            {
                throw new CustomException();
            })));

            semaphore.CurrentCount.ShouldBe(1);
        }
Esempio n. 5
0
        public void WithLockAction_ExceptionInAcquire_ThrowLockException()
        {
            // setup
            var semaphore = new SemaphoreSlim(1);
            var value     = new List();
            var subject   = new AsyncSynchronized <List>(semaphore, value);

            semaphore.Dispose();

            // act and assert
            var exception = Should.Throw <LockException>(() => subject.WithLock((v) =>
            {
            }));

            exception.InnerException.ShouldBeOfType <ObjectDisposedException>();
        }
Esempio n. 6
0
        public async Task LockAsync_Acquire()
        {
            // setup
            var semaphore = new SemaphoreSlim(1);
            var value     = new List();
            var subject   = new AsyncSynchronized <List>(semaphore, value);

            // act and assert
            using (var guard = await subject.LockAsync())
            {
                semaphore.CurrentCount.ShouldBe(0);
                guard.Value.ShouldBe(value);
            }

            semaphore.CurrentCount.ShouldBe(1);
        }
Esempio n. 7
0
        public async Task WithLockAsyncAction_Acquire()
        {
            // setup
            var semaphore = new SemaphoreSlim(1);
            var value     = new List();
            var subject   = new AsyncSynchronized <List>(semaphore, value);

            // act and assert
            await subject.WithLockAsync((v) =>
            {
                semaphore.CurrentCount.ShouldBe(0);
                v.ShouldBe(value);
            });

            semaphore.CurrentCount.ShouldBe(1);
        }
Esempio n. 8
0
        public void WithLockAction_ExceptionInRelease_ThrowUnlockException()
        {
            // setup
            var semaphore = new SemaphoreSlim(1);
            var value     = new List();
            var subject   = new AsyncSynchronized <List>(semaphore, value);

            // act and assert
            var exception = Should.Throw <UnlockException>(() => subject.WithLock((v) =>
            {
                semaphore.Dispose();
            }));

            exception.PriorException.ShouldBeNull();
            exception.InnerExceptions
            .ToDictionary(kv => kv.Key, kv => kv.Value.GetType())
            .ShouldBe(new Dictionary <int, Type>
            {
                [0] = typeof(ObjectDisposedException)
            });
        }
Esempio n. 9
0
        private async Task DiningAsync()
        {
            for (var method = (Method)0; method < Method.Count; ++method)
            {
                for (var nt = 2; nt <= 32; ++nt)
                {
                    ForceGC();
                    var table      = new List <IBareAsyncLock>();
                    var lockOrders = new Dictionary <IBareAsyncLock, int>();
                    for (var i = 0; i < nt; ++i)
                    {
                        table.Add(AsyncSynchronized.Create(new object()));
                        lockOrders[table[i]] = i;
                    }

                    var diners = new List <AsyncPhilosopher>();
                    for (var i = 0; i < nt; ++i)
                    {
                        int j = i;
                        int k = j < nt - 1 ? j + 1 : 0;
                        Func <IReadOnlyList <IBareAsyncLock>, Action, Task> lockToEat = null;
                        switch (method)
                        {
                        case Method.Ordered:
                            lockToEat = async(locks, eat) =>
                            {
                                locks = locks.OrderBy(x => lockOrders[x]).ToList();
                                foreach (var l in locks)
                                {
                                    await l.BarelyLockAsync().ConfigureAwait(false);
                                }
                                eat();
                                foreach (var l in locks)
                                {
                                    l.BarelyUnlock();
                                }
                            };
                            break;

                        case Method.SmartAndPolite:
                            lockToEat = async(locks, eat) =>
                            {
                                using (await MultiSync.AllAsync(locks).ConfigureAwait(false))
                                {
                                    eat();
                                }
                            };
                            break;
                        }
                        diners.Add(new AsyncPhilosopher(new[] { table[j], table[k] }, lockToEat));
                    }
                    var stopwatch = new Stopwatch();
                    var tasks     = new List <Task>();
                    stopwatch.Start();
                    for (var i = 0; i < nt; ++i)
                    {
                        tasks.Add(Task.Run(diners[i].DineAsync));
                    }
                    await Task.WhenAll(tasks).ConfigureAwait(false);

                    stopwatch.Stop();
                    Console.WriteLine($"{method},{nt},{stopwatch.Elapsed.TotalSeconds}");
                }
            }
        }
Esempio n. 10
0
        private async Task TestSynchronizeMultipleAsync(int repeat, bool output)
        {
            var watch = new Stopwatch();

            var x1   = new X();
            var x2   = new X();
            var sqrt = (int)Math.Sqrt(1);

            ForceGC();
            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                lock (x1)
                {
                    lock (x2)
                    {
                        x1.Value += sqrt;
                        x2.Value += sqrt;
                    }
                }
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"lock,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            var syncMonitor1 = Synchronized.Create(x1);
            var syncMonitor2 = Synchronized.Create(x2);

            ForceGC();
            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                using (var v1 = syncMonitor1.Lock())
                    using (var v2 = syncMonitor2.Lock())
                    {
                        v1.Value.Value += sqrt;
                        v2.Value.Value += sqrt;
                    }
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"Synchronized.Lock,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            ForceGC();
            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                using (var guard = MultiSync.All(new[] { syncMonitor1, syncMonitor2 }))
                {
                    guard.Value[0].Value += sqrt;
                    guard.Value[1].Value += sqrt;
                }
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"MultiSync.All Monitor,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            ForceGC();
            var syncMonitors = new[] { syncMonitor1, syncMonitor2 };

            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                using (var guard = MultiSync.All(syncMonitors))
                {
                    guard.Value[0].Value += sqrt;
                    guard.Value[1].Value += sqrt;
                }
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"MultiSync.All Monitor reusing array,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            ForceGC();
            watch.Restart();
            var semaphore1 = new SemaphoreSlim(1);
            var semaphore2 = new SemaphoreSlim(1);

            for (int i = 0; i < repeat; ++i)
            {
                await semaphore1.WaitAsync().ConfigureAwait(false);

                await semaphore2.WaitAsync().ConfigureAwait(false);

                x1.Value += sqrt;
                x2.Value += sqrt;
                semaphore2.Release();
                semaphore1.Release();
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"SemaphoreSlim.WaitAsync,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            ForceGC();
            var syncSemaphore1 = AsyncSynchronized.Create(x1);
            var syncSemaphore2 = AsyncSynchronized.Create(x2);

            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                using (var guard = await MultiSync.AllAsync(new[] { syncSemaphore1, syncSemaphore2 }).ConfigureAwait(false))
                {
                    guard.Value[0].Value += sqrt;
                    guard.Value[1].Value += sqrt;
                }
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"MultiSync.AllAsync SemaphoreSlim,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }
        }
Esempio n. 11
0
        public async Task TestSynchronizedAsync(int repeat, bool output)
        {
            var watch = new Stopwatch();

            var x    = new X();
            var sqrt = (int)Math.Sqrt(1);

            ForceGC();
            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                lock (x)
                {
                    x.Value += sqrt;
                }
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"lock,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            var syncMonitor = Synchronized.Create(x);

            ForceGC();
            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                syncMonitor.WithLock((v) => v.Value += sqrt);
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"Synchronized.WithLock,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            ForceGC();
            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                using (var guard = syncMonitor.Lock())
                {
                    guard.Value.Value += sqrt;
                }
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"Synchronized.Lock,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            ForceGC();
            var semaphore = new SemaphoreSlim(1);

            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                semaphore.Wait();
                x.Value += sqrt;
                semaphore.Release();
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"SemaphoreSlim.Wait,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            var syncSemaphore = AsyncSynchronized.Create(x);

            ForceGC();
            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                syncSemaphore.WithLock((v) => v.Value += sqrt);
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"AsyncSynchronized.WithLock,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            ForceGC();
            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                using (var guard = syncSemaphore.Lock())
                {
                    guard.Value.Value += sqrt;
                }
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"AsyncSynchronized.Lock,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            ForceGC();
            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                await semaphore.WaitAsync().ConfigureAwait(false);

                x.Value += sqrt;
                semaphore.Release();
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"SemaphoreSlim.WaitAsync,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            ForceGC();
            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                await syncSemaphore.WithLockAsync((v) => v.Value += sqrt).ConfigureAwait(false);
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"AsyncSynchronized.WithLockAsync,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            ForceGC();
            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                using (var guard = await syncSemaphore.LockAsync().ConfigureAwait(false))
                {
                    guard.Value.Value += sqrt;
                }
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"AsyncSynchronized.LockAsync,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }
        }