// Begin an asynchronous read of the request entity body. To read the entire entity, invoke // repeatedly until total bytes read is equal to Request.ContentLength or EndRead indicates // that zero bytes were read. If Request.ContentLength is zero and the request is chunked, // then invoke repeatedly until EndRead indicates that zero bytes were read. // // If an error occurs and the client is no longer connected, an HttpException will be thrown. // // This implements Stream.BeginRead, and as such, should throw // exceptions as described on MSDN when errors occur. public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state) { // Do as Stream does. 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")); if (_ecb == IntPtr.Zero) throw new InvalidOperationException(); ReadAsyncResult ar = new ReadAsyncResult(callback, state, buffer, offset, count, updatePerfCounter: false); if (count == 0) { ar.Complete(0, HResults.S_OK, IntPtr.Zero, synchronous: true); return ar; } // we only allow one async operation at a time if (Interlocked.CompareExchange(ref _asyncResultBase, ar, null) != null) throw new InvalidOperationException(SR.GetString(SR.Async_operation_pending)); // initiate async operation here if (_asyncCompletionCallback == null) { _asyncCompletionCallback = new AsyncCompletionCallback(OnAsyncCompletion); } _rootedThis = GCHandle.Alloc(this); // root for duration of async operation int hresult; try { ar.MarkCallToBeginMethodStarted(); hresult = UnsafeNativeMethods.EcbReadClientAsync(_ecb, count, _asyncCompletionCallback); } finally { ar.MarkCallToBeginMethodCompleted(); } if (hresult < 0) { _rootedThis.Free(); _asyncResultBase = null; // treat every error as if the client disconnected IncrementRequestsDisconnected(); throw new HttpException(SR.GetString(SR.ClientDisconnected), hresult); } else { return ar; } }
// Begin an asynchronous read of the request entity body. To read the entire entity, invoke // repeatedly until total bytes read is equal to Request.ContentLength or EndRead indicates // that zero bytes were read. If Request.ContentLength is zero and the request is chunked, // then invoke repeatedly until EndRead indicates that zero bytes were read. // // If an error occurs and the client is no longer connected, an HttpException will be thrown. // // This implements Stream.BeginRead, and as such, should throw // exceptions as described on MSDN when errors occur. public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state) { // Do as Stream does. 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")); ReadAsyncResult ar = new ReadAsyncResult(callback, state, buffer, offset, count, updatePerfCounter: true); if (count == 0) { ar.Complete(0, HResults.S_OK, IntPtr.Zero, synchronous: true); return ar; } // we only allow one async operation at a time if (Interlocked.CompareExchange(ref _asyncResultBase, ar, null) != null) throw new InvalidOperationException(SR.GetString(SR.Async_operation_pending)); // initiate async operation here bool fAsync = true; int bytesRead = 0; IntPtr ppAsyncReceiveBuffer; int hresult = IIS.MgdReadEntityBody(_context, null, // for async the data is copied from a native buffer to avoid pinning 0, // for async, offset is ignored count, // number of bytes to read fAsync, out bytesRead, out ppAsyncReceiveBuffer); if (hresult < 0) { _asyncResultBase = null; // treat every error as if the client disconnected IncrementRequestsDisconnected(); throw new HttpException(SR.GetString(SR.ClientDisconnected), hresult); } // if we completed synchronously, then ppAsyncReceiveBuffer will be non-null else if (ppAsyncReceiveBuffer != IntPtr.Zero) { _asyncResultBase = null; ar.Complete(bytesRead, HResults.S_OK, ppAsyncReceiveBuffer, synchronous: true); return ar; } else { return ar; } }