コード例 #1
0
    // 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;
        }
    }
コード例 #2
0
        // 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;
            }
        }