예제 #1
0
        public void Locked_PreventsLockUntilUnlocked()
        {
            AsyncContext.Run(async () =>
            {
                var monitor = new AsyncMonitor();
                var task1HasLock = new TaskCompletionSource();
                var task1Continue = new TaskCompletionSource();
                Task<IDisposable> initialLockTask = null;

                var task1 = Task.Run(async () =>
                {
                    initialLockTask = monitor.EnterAsync();
                    using (await initialLockTask)
                    {
                        task1HasLock.SetResult();
                        await task1Continue.Task;
                    }
                });
                await task1HasLock.Task;

                var lockTask = monitor.EnterAsync();
                Assert.IsFalse(lockTask.IsCompleted);
                task1Continue.SetResult();
                await lockTask;
            });
        }
예제 #2
0
        public void Unlocked_PermitsLock()
        {
            AsyncContext.Run(async () =>
            {
                var monitor = new AsyncMonitor();

                var task = monitor.EnterAsync();
                await task;
            });
        }
예제 #3
0
        public void Pulse_ReleasesOneWaiter()
        {
            AsyncContext.Run(async () =>
            {
                var monitor = new AsyncMonitor();
                int completed = 0;
                var task1Ready = new TaskCompletionSource();
                var task2Ready = new TaskCompletionSource();
                Task<IDisposable> lockTask1 = null;
                Task waitTask1 = null;
                var task1 = Task.Run(async () =>
                {
                    lockTask1 = monitor.EnterAsync();
                    using (await lockTask1)
                    {
                        waitTask1 = monitor.WaitAsync();
                        task1Ready.SetResult();
                        await waitTask1;
                        Interlocked.Increment(ref completed);
                    }
                });
                await task1Ready.Task;
                Task<IDisposable> lockTask2 = null;
                Task waitTask2 = null;
                var task2 = Task.Run(async () =>
                {
                    lockTask2 = monitor.EnterAsync();
                    using (await lockTask2)
                    {
                        waitTask2 = monitor.WaitAsync();
                        task2Ready.SetResult();
                        await waitTask2;
                        Interlocked.Increment(ref completed);
                    }
                });
                await task2Ready.Task;

                Task<IDisposable> lockTask3 = monitor.EnterAsync();
                using (await lockTask3)
                {
                    monitor.Pulse();
                }
                await Task.WhenAny(task1, task2);
                var result = Interlocked.CompareExchange(ref completed, 0, 0);

                Assert.AreEqual(1, result);
            });
        }
예제 #4
0
        public void Pulse_ReleasesOneWaiter()
        {
            Test.Async(async () =>
            {
                var monitor = new AsyncMonitor();
                int completed = 0;
                var task1Ready = new TaskCompletionSource();
                var task2Ready = new TaskCompletionSource();
                var task1 = TaskShim.Run(async () =>
                {
                    using (await monitor.EnterAsync())
                    {
                        var waitTask1 = monitor.WaitAsync();
                        task1Ready.SetResult();
                        await waitTask1;
                        Interlocked.Increment(ref completed);
                    }
                });
                await task1Ready.Task;
                var task2 = TaskShim.Run(async () =>
                {
                    using (await monitor.EnterAsync())
                    {
                        var waitTask2 = monitor.WaitAsync();
                        task2Ready.SetResult();
                        await waitTask2;
                        Interlocked.Increment(ref completed);
                    }
                });
                await task2Ready.Task;

                using (await monitor.EnterAsync())
                {
                    monitor.Pulse();
                }
                await TaskShim.WhenAny(task1, task2);
                var result = Interlocked.CompareExchange(ref completed, 0, 0);

                Assert.AreEqual(1, result);
            });
        }
예제 #5
0
        public async Task WillPulseMonitor() {
            var monitor = new AsyncMonitor();
            var sw = Stopwatch.StartNew();
            // Monitor will not be pulsed and should be cancelled after 100ms.
            using (await monitor.EnterAsync())
                await Assert.ThrowsAsync<TaskCanceledException>(async () =>
                    await monitor.WaitAsync(TimeSpan.FromMilliseconds(100).ToCancellationToken()));
            sw.Stop();
            Assert.InRange(sw.ElapsedMilliseconds, 75, 125);

            var t = Task.Run(async () => {
                await Task.Delay(25);
                using (await monitor.EnterAsync())
                    monitor.Pulse();
            });

            sw = Stopwatch.StartNew();
            using (await monitor.EnterAsync())
                await monitor.WaitAsync(TimeSpan.FromSeconds(1).ToCancellationToken());
            sw.Stop();
            Assert.InRange(sw.ElapsedMilliseconds, 25, 100);
        }
예제 #6
0
        public void Locked_PreventsLockUntilUnlocked()
        {
            Test.Async(async () =>
            {
                var monitor = new AsyncMonitor();
                var task1HasLock = new TaskCompletionSource();
                var task1Continue = new TaskCompletionSource();

                var task1 = TaskShim.Run(async () =>
                {
                    using (await monitor.EnterAsync())
                    {
                        task1HasLock.SetResult();
                        await task1Continue.Task;
                    }
                });
                await task1HasLock.Task;

                var lockTask = monitor.EnterAsync().AsTask();
                Assert.IsFalse(lockTask.IsCompleted);
                task1Continue.SetResult();
                await lockTask;
            });
        }
예제 #7
0
 public void Id_IsNotZero()
 {
     var monitor = new AsyncMonitor();
     Assert.AreNotEqual(0, monitor.Id);
 }