public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback cb, object state) { if (disposed) { throw new WebException("stream is closed", WebExceptionStatus.ConnectionClosed); } if (!isRead) { throw new NotSupportedException("this stream does not allow reading"); } if (buffer == null) { throw new ArgumentNullException("buffer"); } int length = buffer.Length; if (offset < 0 || length < offset) { throw new ArgumentOutOfRangeException("offset"); } if (size < 0 || (length - offset) < size) { throw new ArgumentOutOfRangeException("size"); } lock (locker) { pendingReads++; pending.Reset(); } WebAsyncResult result = new WebAsyncResult(cb, state, buffer, offset, size); if (totalRead >= contentLength) { result.SetCompleted(true, -1); result.DoCallback(); return(result); } int remaining = readBufferSize - readBufferOffset; if (remaining > 0) { int copy = (remaining > size) ? size : remaining; Buffer.BlockCopy(readBuffer, readBufferOffset, buffer, offset, copy); readBufferOffset += copy; offset += copy; size -= copy; totalRead += copy; if (size == 0 || totalRead >= contentLength) { result.SetCompleted(true, copy); result.DoCallback(); return(result); } result.NBytes = copy; } if (cb != null) { cb = cb_wrapper; } if (contentLength != Int32.MaxValue && contentLength - totalRead < size) { size = contentLength - totalRead; } if (!read_eof) { result.InnerAsyncResult = cnc.BeginRead(request, buffer, offset, size, cb, result); } else { result.SetCompleted(true, result.NBytes); result.DoCallback(); } return(result); }