public void UnblockDoSomething() { using (await _mutex.LockAsync()) { DoWork(); _cv.Notify(); } }
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; }
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); }