// Caller may invoke this repeatedly until EndRead returns zero, at which point the entire entity has been read. public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state) { HttpWorkerRequest wr = _context.WorkerRequest; // Only perform an async read if the worker request supports it and we're not in a cancellable period. // If we were to allow async read in a cancellable period, the timeout manager could raise a ThreadAbortEx and // corrupt the state of the request. if (wr != null && wr.SupportsAsyncRead && !_context.IsInCancellablePeriod) { if (!_preloadedContentRead) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset"); } if (count < 0) { throw new ArgumentOutOfRangeException("count"); } if (buffer.Length - offset < count) { throw new ArgumentException(SR.GetString(SR.InvalidOffsetOrCount, "offset", "count")); } _preloadedBytesRead = GetPreloadedContent(buffer, ref offset, ref count); } if (_remainingBytes == 0) { // set count to zero and invoke BeginRead to return an async result count = 0; } if (_persistEntityBody) { // hold a reference so we can add bytes to _rawContent when EndRead is called _buffer = buffer; _offset = offset; _count = count; } try { return(wr.BeginRead(buffer, offset, count, callback, state)); } catch (HttpException) { if (_persistEntityBody) { SetRawContentOnce(); } throw; } } else { // perform a sync read return(base.BeginRead(buffer, offset, count, callback, state)); } }