// Begin an asynchronous flush of the response.  To support this, the worker request buffers
        // the status, headers, and resonse body until an asynchronous flush operation is initiated.
        public override IAsyncResult BeginFlush(AsyncCallback callback, Object state) {
            if (_context == IntPtr.Zero) {
                throw new InvalidOperationException();
            }

            FlushAsyncResult ar = new FlushAsyncResult(callback, state);

            // 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 async = true;
            bool completedSynchronously;
            int hresult = IIS.MgdExplicitFlush(_context, async, out completedSynchronously);

            if (hresult < 0) {
                _asyncResultBase = null;
                // treat every error as if the client disconnected
                IncrementRequestsDisconnected();
                throw new HttpException(SR.GetString(SR.ClientDisconnected), hresult);
            }
            else if (completedSynchronously) {
                _asyncResultBase = null;
                ar.Complete(0, HResults.S_OK, IntPtr.Zero, synchronous: true);
                return ar;
            }
            else {
                return ar;
            }
        }
    // Begin an asynchronous flush of the response.  To support this, the worker request buffers
    // the status, headers, and resonse body until an asynchronous flush operation is initiated.
    public override IAsyncResult BeginFlush(AsyncCallback callback, Object state) {
        if (_ecb == IntPtr.Zero) {
            throw new InvalidOperationException();
        }
        
        FlushAsyncResult ar = new FlushAsyncResult(callback, state);
        
        // 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);
        }

        try {
            ar.MarkCallToBeginMethodStarted();
            FlushResponse(finalFlush: false);
        }
        finally {
            ar.MarkCallToBeginMethodCompleted();
        }

        return ar;
    }
        // Sends the currently buffered response to the client.  If the underlying HttpWorkerRequest
        // supports asynchronous flush and this method is called from an asynchronous module event
        // or asynchronous handler, then the send will be performed asynchronously.  Otherwise the
        // implementation resorts to a synchronous flush.  The HttpResponse.SupportsAsyncFlush property 
        // returns the value of HttpWorkerRequest.SupportsAsyncFlush.  Asynchronous flush is supported
        // for IIS 6.0 and higher.
        public IAsyncResult BeginFlush(AsyncCallback callback, Object state) {
            if (_completed)
                throw new HttpException(SR.GetString(SR.Cannot_flush_completed_response));

            // perform async flush if it is supported
            if (_wr != null && _wr.SupportsAsyncFlush && !_context.IsInCancellablePeriod) {
                Flush(false, true);
                return _wr.BeginFlush(callback, state);
            }

            // perform a [....] flush since async is not supported
            FlushAsyncResult ar = new FlushAsyncResult(callback, state);
            try {
                Flush(false);
            }
            catch(Exception e) {
                ar.SetError(e);
            }
            ar.Complete(0, HResults.S_OK, IntPtr.Zero, synchronous: true);
            return ar;
        }