Example #1
0
        public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
        {
            if (_chunks == null)
            {
                throw new ObjectDisposedException(nameof(DuplexStream));
            }

            if (_chunks.Count == 0 && _writeClosed)
            {
                return(0);
            }

            SemaphoreLock semaphoreLock = await SemaphoreLock.GetLockAsync(_semaphore, cancellationToken);

            try
            {
                while (_chunks.Count == 0)
                {
                    if (_writeClosed)
                    {
                        return(0);
                    }
                    semaphoreLock.Dispose();
                    semaphoreLock = null;
                    await _newData.WaitAsync(cancellationToken);

                    semaphoreLock = await SemaphoreLock.GetLockAsync(_semaphore, cancellationToken);
                }

                cancellationToken.ThrowIfCancellationRequested();

                LinkedListNode <byte[]> node = _chunks.First;
                _chunks.Remove(node);
                byte[] value  = node.Value;
                int    toCopy = Math.Min(value.Length, count);
                Array.Copy(value, 0, buffer, offset, toCopy);
                if (toCopy != value.Length)
                {
                    int remLength = value.Length - toCopy;
                    var remainder = new byte[remLength];
                    Array.Copy(value, toCopy, remainder, 0, remLength);
                    _chunks.AddFirst(remainder);
                }
                return(toCopy);
            }
            finally
            {
                semaphoreLock?.Dispose();
            }
        }
Example #2
0
        public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
        {
            if (_writeClosed)
            {
                throw new InvalidOperationException();
            }
            if (_chunks == null)
            {
                throw new ObjectDisposedException(nameof(DuplexStream));
            }

            var insert = new byte[count];

            Array.Copy(buffer, offset, insert, 0, count);
            using (await SemaphoreLock.GetLockAsync(_semaphore, cancellationToken))
            {
                _chunks.AddLast(insert);
            }

            _newData.Set();
        }