Exemple #1
0
 public void UnblockDoSomething()
 {
     using (await _mutex.LockAsync())
     {
         DoWork();
         _cv.Notify();
     }
 }
Exemple #2
0
        public async Task AddAsync(T item)
        {
            using (await mutex.LockAsync())
            {
                while (Full)
                {
                    await notFull.WaitAsync();
                }

                if (!collection.TryAdd(item))
                {
                    throw new InvalidOperationException("The underlying collection refused the item.");
                }
                notEmpty.Notify();
            }
        }
        public async Task WaitAsync_AfterNotify_IsNotCompleted()
        {
            AsyncLock mutex           = new AsyncLock();
            AsyncConditionVariable cv = new AsyncConditionVariable(mutex);
            await Task.Run(async() =>
            {
                using (await mutex.LockAsync())
                {
                    cv.Notify();
                }
            }).ConfigureAwait(false);

            await mutex.LockAsync();

            Task task = cv.WaitAsync();

            await AsyncAssert.NeverCompletesAsync(task).ConfigureAwait(false);
        }
        public async Task WaitAsync_Notified_IsCompleted()
        {
            AsyncLock mutex           = new AsyncLock();
            AsyncConditionVariable cv = new AsyncConditionVariable(mutex);
            await mutex.LockAsync();

            Task task = cv.WaitAsync();

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

            await task;
        }
Exemple #5
0
        public async Task <T> TakeAsync()
        {
            using (await mutex.LockAsync())
            {
                while (Empty)
                {
                    await notEmpty.WaitAsync();
                }

                T ret;
                if (!collection.TryTake(out ret))
                {
                    throw new InvalidOperationException("The underlying collection refused to provide an item.");
                }
                notFull.Notify();
                return(ret);
            }
        }
        public async Task WaitAsync_AfterNotify_IsNotCompleted()
        {
            var mutex = new AsyncLock();
            var cv    = new AsyncConditionVariable(mutex);
            await Task.Run(async() =>
            {
                using (await mutex.LockAsync())
                {
                    cv.Notify();
                }
            });

            await mutex.LockAsync();

            var task = cv.WaitAsync();

            await AsyncAssert.NeverCompletesAsync(task);
        }
        public async Task WaitAsync_Notified_IsCompleted()
        {
            var mutex = new AsyncLock();
            var cv    = new AsyncConditionVariable(mutex);
            await mutex.LockAsync();

            var task = cv.WaitAsync();

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

            await task;
        }
        private async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken, bool sync)
        {
            using (sync ? _mutex.Lock(cancellationToken) : await _mutex.LockAsync(cancellationToken).ConfigureAwait(false))
            {
                while (Empty && !_completed)
                {
                    if (sync)
                    {
                        _notEmptyOrCompleted.Wait(cancellationToken);
                    }
                    else
                    {
                        await _notEmptyOrCompleted.WaitAsync(cancellationToken).ConfigureAwait(false);
                    }
                }
                cancellationToken.ThrowIfCancellationRequested();

                if (AvailableToRead == 0)
                {
                    return(0);
                }

                // Copy the data from the stream
                var bytesToCopy = Math.Min(count, AvailableToRead);
                Array.Copy(_data.First.Value, _headDataBytesRead, buffer, offset, bytesToCopy);

                // Remove those bytes from the stream
                if (bytesToCopy == AvailableToRead)
                {
                    _data.RemoveFirst();
                    _headDataBytesRead = 0;
                }
                else
                {
                    _headDataBytesRead += bytesToCopy;
                }
                _currentBytes  -= bytesToCopy;
                ReaderPosition += bytesToCopy;

                _notFullOrCompleted.Notify();
                return(bytesToCopy);
            }
        }
        private async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken, bool sync)
        {
            using (sync ? _mutex.Lock(cancellationToken) : await _mutex.LockAsync(cancellationToken).ConfigureAwait(false))
            {
                while (count != 0)
                {
                    while (Full && !_completed)
                    {
                        if (sync)
                        {
                            _notFullOrCompleted.Wait(cancellationToken);
                        }
                        else
                        {
                            await _notFullOrCompleted.WaitAsync(cancellationToken).ConfigureAwait(false);
                        }
                    }
                    if (_completed)
                    {
                        throw new OperationCanceledException("Stream has been closed for writing.");
                    }
                    cancellationToken.ThrowIfCancellationRequested();

                    // Copy the data
                    var bytesToCopy = Math.Min(count, AvailableToWrite);
                    var data        = new byte[bytesToCopy];
                    Array.Copy(buffer, offset, data, 0, bytesToCopy);

                    // Add it to the stream
                    _data.AddLast(data);
                    _currentBytes  += bytesToCopy;
                    WriterPosition += bytesToCopy;

                    // Adjust status of current operation
                    offset += bytesToCopy;
                    count  -= bytesToCopy;

                    _notEmptyOrCompleted.Notify();
                }
            }
        }
        public async Task MultipleWaits_Notify_OneIsCompleted()
        {
            AsyncLock mutex            = new AsyncLock();
            AsyncConditionVariable cv  = new AsyncConditionVariable(mutex);
            IDisposable            key = await mutex.LockAsync();

            Task task1 = cv.WaitAsync();
            Task __    = task1.ContinueWith(_ => key.Dispose());
            await mutex.LockAsync();

            Task task2 = cv.WaitAsync();

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

            await task1;
            await AsyncAssert.NeverCompletesAsync(task2).ConfigureAwait(false);
        }
        public async Task MultipleWaits_Notify_OneIsCompleted()
        {
            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 Task.Run(async() =>
            {
                using (await mutex.LockAsync())
                {
                    cv.Notify();
                }
            });

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