public override IAsyncResult BeginWrite(byte[] array, int offset, int count, AsyncCallback asyncCallback, object asyncState)
        {
            this.EnsureCompressionMode();

            // We use this checking order for compat to earlier versions:
            if (_asyncOperations != 0)
                throw new InvalidOperationException();

            this.ValidateParameters(array, offset, count);
            this.EnsureNotDisposed();

            Interlocked.Increment(ref _asyncOperations);

            try
            {

                var userResult = new DeflateStreamAsyncResult(asyncState, asyncCallback, array, offset, count);

                _asyncWriterDelegate.BeginInvoke(array, offset, count, true, _callBack, userResult);
                userResult.CompletedSynchronously &= userResult.IsCompleted;

                return userResult;

            }
            catch
            {
                Interlocked.Decrement(ref _asyncOperations);
                throw;
            }
        }
 private void AwaitAsyncResultCompletion(DeflateStreamAsyncResult asyncResult)
 {
     try
     {
         if (!asyncResult.IsCompleted)
             asyncResult.AsyncWaitHandle.WaitOne();
     }
     finally
     {
         Interlocked.Decrement(ref _asyncOperations);
         asyncResult.Close();  // this will just close the wait handle
     }
 }
        public override IAsyncResult BeginRead(byte[] array, int offset, int count, AsyncCallback asyncCallback, object asyncState)
        {
            this.EnsureDecompressionMode();

            // We use this checking order for compat to earlier versions:
            if (_asyncOperations != 0)
                throw new InvalidOperationException();

            this.ValidateParameters(array, offset, count);
            this.EnsureNotDisposed();

            Interlocked.Increment(ref _asyncOperations);

            try
            {
                var userResult = new DeflateStreamAsyncResult(asyncState, asyncCallback, array, offset, count);

                // Try to read decompressed data in output buffer
                var bytesRead = _inflater.Inflate(array, offset, count);
                if (bytesRead != 0)
                {
                    // If decompression output buffer is not empty, return immediately.
                    // 'true' means we complete synchronously.
                    userResult.InvokeCallback(true, bytesRead);
                    return userResult;
                }

                if (_inflater.Finished())
                {
                    // end of compression stream
                    userResult.InvokeCallback(true, 0);
                    return userResult;
                }

                // If there is no data on the output buffer and we are not at 
                // the end of the stream, we need to get more data from the base stream
                this.BaseStream.BeginRead(_buffer, 0, _buffer.Length, _callBack, userResult);
                userResult.CompletedSynchronously &= userResult.IsCompleted;

                return userResult;

            }
            catch
            {
                Interlocked.Decrement(ref _asyncOperations);
                throw;
            }
        }