public void MultipleWaits_NotifyAll_AllAreCompleted()
        {
            AsyncContext.Run(async () =>
            {
                var mutex = new AsyncLock();
                var cv = new AsyncConditionVariable(mutex);
                var key1 = await mutex.LockAsync();
                var task1 = cv.WaitAsync();
                var __ = task1.ContinueWith(_ => key1.Dispose());
                var key2 = await mutex.LockAsync();
                var task2 = cv.WaitAsync();
                var ___ = task2.ContinueWith(_ => key2.Dispose());

                await Task.Run(async () =>
                {
                    using (await mutex.LockAsync())
                    {
                        cv.NotifyAll();
                    }
                });

                await task1;
                await task2;
            });
        }
        public void WaitAsync_WithoutNotify_IsNotCompleted()
        {
            Test.Async(async () =>
            {
                var mutex = new AsyncLock();
                var cv = new AsyncConditionVariable(mutex);

                await mutex.LockAsync();
                var task = cv.WaitAsync();

                await AssertEx.NeverCompletesAsync(task);
            });
        }
예제 #3
0
        /// <summary>
        /// Creates a new async-compatible producer/consumer queue with the specified initial elements and a maximum element count.
        /// </summary>
        /// <param name="collection">The initial elements to place in the queue. This may be <c>null</c> to start with an empty collection.</param>
        /// <param name="maxCount">The maximum element count. This must be greater than zero, and greater than or equal to the number of elements in <paramref name="collection"/>.</param>
        public AsyncProducerConsumerQueue(IEnumerable <T> collection, int maxCount)
        {
            if (maxCount <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(maxCount), "The maximum count must be greater than zero.");
            }
            _queue = collection == null ? new Queue <T>() : new Queue <T>(collection);
            if (maxCount < _queue.Count)
            {
                throw new ArgumentException("The maximum count cannot be less than the number of elements in the collection.", nameof(maxCount));
            }
            _maxCount = maxCount;

            _mutex = new AsyncLock();
            _completedOrNotFull  = new AsyncConditionVariable(_mutex);
            _completedOrNotEmpty = new AsyncConditionVariable(_mutex);
        }
예제 #4
0
 /// <summary>
 /// Creates a new async-compatible producer/consumer collection wrapping the specified collection and with a maximum element count.
 /// </summary>
 /// <param name="collection">The collection to wrap.</param>
 /// <param name="maxCount">The maximum element count. This must be greater than zero.</param>
 public AsyncCollection(IProducerConsumerCollection <T>?collection, int maxCount)
 {
     collection ??= new ConcurrentQueue <T>();
     if (maxCount <= 0)
     {
         throw new ArgumentOutOfRangeException(nameof(maxCount), "The maximum count must be greater than zero.");
     }
     if (maxCount < collection.Count)
     {
         throw new ArgumentException("The maximum count cannot be less than the number of elements in the collection.", nameof(maxCount));
     }
     _collection          = collection;
     _maxCount            = maxCount;
     _mutex               = new AsyncLock();
     _completedOrNotFull  = new AsyncConditionVariable(_mutex);
     _completedOrNotEmpty = new AsyncConditionVariable(_mutex);
 }
        public void WaitAsync_Notified_IsCompleted()
        {
            Test.Async(async () =>
            {
                var mutex = new AsyncLock();
                var cv = new AsyncConditionVariable(mutex);
                await mutex.LockAsync();
                var task = cv.WaitAsync();

                await TaskShim.Run(async () =>
                {
                    using (await mutex.LockAsync())
                    {
                        cv.Notify();
                    }
                });
                await task;
            });
        }
        public void WaitAsync_AfterNotify_IsNotCompleted()
        {
            Test.Async(async () =>
            {
                var mutex = new AsyncLock();
                var cv = new AsyncConditionVariable(mutex);
                await TaskShim.Run(async () =>
                {
                    using (await mutex.LockAsync())
                    {
                        cv.Notify();
                    }
                });

                await mutex.LockAsync();
                var task = cv.WaitAsync();

                await AssertEx.NeverCompletesAsync(task);
            });
        }
예제 #7
0
 /// <summary>
 /// Constructs a new monitor.
 /// </summary>
 public AsyncMonitor(IAsyncWaitQueue <IDisposable> lockQueue, IAsyncWaitQueue <object> conditionVariableQueue)
 {
     _asyncLock         = new AsyncLock(lockQueue);
     _conditionVariable = new AsyncConditionVariable(_asyncLock, conditionVariableQueue);
     //Enlightenment.Trace.AsyncMonitor_Created(_asyncLock, _conditionVariable);
 }
예제 #8
0
 public DebugView(AsyncConditionVariable cv)
 {
     _cv = cv;
 }
예제 #9
0
 /// <summary>
 /// Constructs a new monitor.
 /// </summary>
 public AsyncMonitor(IAsyncWaitQueue<IDisposable> lockQueue, IAsyncWaitQueue<object> conditionVariableQueue)
 {
     _asyncLock = new AsyncLock(lockQueue);
     _conditionVariable = new AsyncConditionVariable(_asyncLock, conditionVariableQueue);
     //Enlightenment.Trace.AsyncMonitor_Created(_asyncLock, _conditionVariable);
 }
예제 #10
0
 /// <summary>
 /// Constructs a new monitor.
 /// </summary>
 /// <param name="lockQueue">The wait queue used to manage waiters for the lock. This may be <c>null</c> to use a default (FIFO) queue.</param>
 /// <param name="conditionVariableQueue">The wait queue used to manage waiters for the signal. This may be <c>null</c> to use a default (FIFO) queue.</param>
 internal AsyncMonitor(IAsyncWaitQueue <IDisposable>?lockQueue, IAsyncWaitQueue <object>?conditionVariableQueue)
 {
     _asyncLock         = new AsyncLock(lockQueue);
     _conditionVariable = new AsyncConditionVariable(_asyncLock, conditionVariableQueue);
 }
 public DebugView(AsyncConditionVariable cv)
 {
     _cv = cv;
 }
 public void Id_IsNotZero()
 {
     var mutex = new AsyncLock();
     var cv = new AsyncConditionVariable(mutex);
     Assert.AreNotEqual(0, cv.Id);
 }
        public void MultipleWaits_Notify_OneIsCompleted()
        {
            Test.Async(async () =>
            {
                var mutex = new AsyncLock();
                var cv = new AsyncConditionVariable(mutex);
                var key = await mutex.LockAsync();
                var task1 = cv.WaitAsync();
                var __ = task1.ContinueWith(_ => key.Dispose());
                await mutex.LockAsync();
                var task2 = cv.WaitAsync();

                await TaskShim.Run(async () =>
                {
                    using (await mutex.LockAsync())
                    {
                        cv.Notify();
                    }
                });

                await task1;
                await AssertEx.NeverCompletesAsync(task2);
            });
        }