System.IO.BufferedStream.ReadFromUnderlyingStreamAsync C# (CSharp) Méthode

ReadFromUnderlyingStreamAsync() private méthode

BufferedStream should be as thin a wrapper as possible. We want ReadAsync to delegate to ReadAsync of the underlying _stream rather than calling the base Stream which implements the one in terms of the other. This allows BufferedStream to affect the semantics of the stream it wraps as little as possible.
private ReadFromUnderlyingStreamAsync ( byte array, int offset, int count, CancellationToken cancellationToken, int bytesAlreadySatisfied, Task semaphoreLockTask ) : Task
array byte
offset int
count int
cancellationToken CancellationToken
bytesAlreadySatisfied int
semaphoreLockTask Task
Résultat Task
        private async Task<int> ReadFromUnderlyingStreamAsync(byte[] array, int offset, int count,
                                                                CancellationToken cancellationToken,
                                                                int bytesAlreadySatisfied,
                                                                Task semaphoreLockTask)
        {

            // Same conditions validated with exceptions in ReadAsync:
            // (These should be Debug.Requires(..) but that method had some issues in async methods; using Assert(..) for now.)
            Debug.Assert(array != null);
            Debug.Assert(offset >= 0);
            Debug.Assert(count >= 0);
            Debug.Assert(array.Length - offset >= count);
            Debug.Assert(_stream != null);
            Debug.Assert(_stream.CanRead);
            Debug.Assert(_bufferSize > 0);
            Debug.Assert(semaphoreLockTask != null);

            // Employ async waiting based on the same synchronization used in BeginRead of the abstract Stream.        
            await semaphoreLockTask.ConfigureAwait(false);
            try
            {

                // The buffer might have been changed by another async task while we were waiting on the semaphore.
                // Check it now again.            
                int bytesFromBuffer = ReadFromBuffer(array, offset, count);
                if (bytesFromBuffer == count)
                    return bytesAlreadySatisfied + bytesFromBuffer;

                if (bytesFromBuffer > 0)
                {
                    count -= bytesFromBuffer;
                    offset += bytesFromBuffer;
                    bytesAlreadySatisfied += bytesFromBuffer;
                }

                Debug.Assert(_readLen == _readPos);
                _readPos = _readLen = 0;

                // If there was anything in the write buffer, clear it.
                if (_writePos > 0)
                    await FlushWriteAsync(cancellationToken).ConfigureAwait(false);  // no Begin-End read version for Flush. Use Async.            

                // If the requested read is larger than buffer size, avoid the buffer and still use a single read:
                if (count >= _bufferSize)
                {
                    return bytesAlreadySatisfied + await _stream.ReadAsync(array, offset, count, cancellationToken).ConfigureAwait(false);
                }

                // Ok. We can fill the buffer:
                EnsureBufferAllocated();
                _readLen = await _stream.ReadAsync(_buffer, 0, _bufferSize, cancellationToken).ConfigureAwait(false);

                bytesFromBuffer = ReadFromBuffer(array, offset, count);
                return bytesAlreadySatisfied + bytesFromBuffer;

            }
            finally
            {
                SemaphoreSlim sem = LazyEnsureAsyncActiveSemaphoreInitialized();
                sem.Release();
            }
        }