public void AsyncLockShouldAllowOnlyOneThread()
        {
            var block = new SemaphoreSlim(0, 2);
            var count = 0;
            var alock = new AsyncLock();

            var firstCall = Task.Factory.StartNew(async () =>
            {
                using (await alock.LockAsync())
                {
                    Interlocked.Increment(ref count);
                    block.Wait();
                }
                block.Wait();//keep this thread busy
            });

            TaskTest.WaitFor(() => count > 0);

            alock.LockAsync().ContinueWith(t => Interlocked.Increment(ref count));

            Assert.That(count, Is.EqualTo(1), "Only one task should have gotten past lock.");
            Assert.That(firstCall.IsCompleted, Is.False, "Task should still be running.");

            block.Release();
            TaskTest.WaitFor(() => count > 1);
            Assert.That(count, Is.EqualTo(2), "Second call should get past lock.");
            Assert.That(firstCall.IsCompleted, Is.False, "First call should still be busy.");
            block.Release();
        }
Esempio n. 2
0
        public async void AsyncLockCancelShouldThrowOperationCanceledException()
        {
            var count = 0;
            var token = new CancellationTokenSource(TimeSpan.FromMilliseconds(10));
            var alock = new AsyncLock();

            for (int i = 0; i < 2; i++)
            {
                //the second call will timeout
                using (await alock.LockAsync(token.Token))
                {
                    Interlocked.Increment(ref count);
                    Thread.Sleep(100);
                }
            }
            Assert.That(count, Is.EqualTo(1), "Only the first call should succeed.  The second should timeout.");
        }
        public void AsyncLockShouldAllowMultipleStackedWaits()
        {
            var count = 0;
            var alock = new AsyncLock();
            var locks = new List<Task<AsyncLock.Releaser>>();
            for (int i = 0; i < 1000; i++)
            {
                var task = alock.LockAsync();
                task.ContinueWith(t => Interlocked.Increment(ref count));
                locks.Add(task);
            }

            for (int i = 0; i < 100; i++)
            {
                using (locks[i].Result)
                {
                    Thread.Sleep(10);
                    Assert.That(count, Is.EqualTo(i + 1));
                }
            }
        }
        public void AsyncLockShouldUnlockEvenFromDifferentThreads()
        {
            var block = new SemaphoreSlim(0, 2);
            var count = 0;
            var alock = new AsyncLock();

            Task.Factory.StartNew(async () =>
            {
                using (await alock.LockAsync().ConfigureAwait(false))
                {
                    Console.WriteLine("Enter lock id: {0}", Thread.CurrentThread.ManagedThreadId);
                    Interlocked.Increment(ref count);
                    await ExternalThread();
                    await block.WaitAsync();
                    Console.WriteLine("Exit lock id: {0}", Thread.CurrentThread.ManagedThreadId);
                }
            });

            TaskTest.WaitFor(() => count > 0);

            Task.Factory.StartNew(async () =>
            {
                Console.WriteLine("Second call waiting Id:{0}", Thread.CurrentThread.ManagedThreadId);
                using (await alock.LockAsync().ConfigureAwait(false))
                {
                    Console.WriteLine("Past lock Id:{0}", Thread.CurrentThread.ManagedThreadId);
                    Interlocked.Increment(ref count);
                }
            }, TaskCreationOptions.LongRunning);

            Assert.That(count, Is.EqualTo(1), "Only one task should have gotten past lock.");

            block.Release();
            TaskTest.WaitFor(() => count > 1);
            Assert.That(count, Is.EqualTo(2), "Second call should get past lock.");
        }
Esempio n. 5
0
        public async void AsyncLockCancelShouldNotAllowInsideLock()
        {
            var count = 0;
            var token = new CancellationTokenSource(TimeSpan.FromMilliseconds(10));
            var alock = new AsyncLock();

            try
            {
                for (int i = 0; i < 2; i++)
                {
                    //the second call will timeout
                    using (await alock.LockAsync(token.Token))
                    {
                        Interlocked.Increment(ref count);
                        Thread.Sleep(100);
                    }
                }
            }
            catch 
            {
            }

            Assert.That(count, Is.EqualTo(1));
        }
Esempio n. 6
0
 internal Releaser(AsyncLock toRelease)
 {
     _toRelease = toRelease;
 }
Esempio n. 7
0
 internal Releaser(AsyncLock toRelease)
 {
     _toRelease = toRelease;
 }