Ejemplo n.º 1
0
        // 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));
            }
        }