private async Task WriteAsyncCore(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
        {
            if (WebSocketBase.LoggingEnabled)
            {
                Logging.Enter(Logging.WebSockets, this, Methods.WriteAsyncCore,
                              WebSocketHelpers.GetTraceMsgForParameters(offset, count, cancellationToken));
            }

            CancellationTokenRegistration cancellationTokenRegistration = new CancellationTokenRegistration();

            try
            {
                if (cancellationToken.CanBeCanceled)
                {
                    cancellationTokenRegistration = cancellationToken.Register(s_OnCancel, this, false);
                }

                if (!m_InOpaqueMode)
                {
                    await m_OutputStream.WriteAsync(buffer, offset, count, cancellationToken).SuppressContextFlow();
                }
                else
                {
#if DEBUG
                    // When using fast path only one outstanding read is permitted. By switching into opaque mode
                    // via IWebSocketStream.SwitchToOpaqueMode (see more detailed comments in interface definition)
                    // caller takes responsibility for enforcing this constraint.
                    Contract.Assert(Interlocked.Increment(ref m_OutstandingOperations.m_Writes) == 1,
                                    "Only one outstanding write allowed at any given time.");
#endif
                    m_WriteTaskCompletionSource = new TaskCompletionSource <object>();
                    m_WriteEventArgs.BufferList = null;
                    m_WriteEventArgs.SetBuffer(buffer, offset, count);
                    if (WriteAsyncFast(m_WriteEventArgs))
                    {
                        await m_WriteTaskCompletionSource.Task.SuppressContextFlow();
                    }
                }
            }
            catch (Exception error)
            {
                if (s_CanHandleException(error))
                {
                    cancellationToken.ThrowIfCancellationRequested();
                }

                throw;
            }
            finally
            {
                cancellationTokenRegistration.Dispose();

                if (WebSocketBase.LoggingEnabled)
                {
                    Logging.Exit(Logging.WebSockets, this, Methods.WriteAsyncCore, string.Empty);
                }
            }
        }
            public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
            {
                WebSocketHelpers.ValidateBuffer(buffer, offset, count);

                if (!m_InOpaqueMode)
                {
                    return(base.WriteAsync(buffer, offset, count, cancellationToken));
                }

                if (WebSocketBase.LoggingEnabled)
                {
                    Logging.Enter(Logging.WebSockets, this, Methods.WriteAsync,
                                  WebSocketHelpers.GetTraceMsgForParameters(offset, count, cancellationToken));
                }

                bool completedAsynchronously = false;

                try
                {
                    cancellationToken.ThrowIfCancellationRequested();
#if DEBUG
                    // When using fast path only one outstanding read is permitted. By switching into opaque mode
                    // via IWebSocketStream.SwitchToOpaqueMode (see more detailed comments in interface definition)
                    // caller takes responsibility for enforcing this constraint.
                    Contract.Assert(Interlocked.Increment(ref m_OutstandingOperations.m_Writes) == 1,
                                    "Only one outstanding write allowed at any given time.");
#endif
                    WebSocketHelpers.ThrowIfConnectionAborted(m_InnerStream, false);
                    m_WriteTaskCompletionSource = new TaskCompletionSource <object>();
                    m_WriteEventArgs.BufferList = null;
                    m_WriteEventArgs.SetBuffer(buffer, offset, count);
                    completedAsynchronously = InnerSocket.SendAsync(m_WriteEventArgs);
                    if (!completedAsynchronously)
                    {
                        if (m_WriteEventArgs.SocketError != SocketError.Success)
                        {
                            throw new SocketException(m_WriteEventArgs.SocketError);
                        }

                        return(Task.CompletedTask);
                    }

                    return(m_WriteTaskCompletionSource.Task);
                }
                finally
                {
                    if (WebSocketBase.LoggingEnabled)
                    {
                        Logging.Exit(Logging.WebSockets, this, Methods.WriteAsync, completedAsynchronously);
                    }
                }
            }
        public async override Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
        {
            if (WebSocketBase.LoggingEnabled)
            {
                Logging.Enter(Logging.WebSockets, this, Methods.ReadAsync,
                              WebSocketHelpers.GetTraceMsgForParameters(offset, count, cancellationToken));
            }

            CancellationTokenRegistration cancellationTokenRegistration = new CancellationTokenRegistration();

            int bytesRead = 0;

            try
            {
                if (cancellationToken.CanBeCanceled)
                {
                    cancellationTokenRegistration = cancellationToken.Register(s_OnCancel, this, false);
                }

                WebSocketHelpers.ThrowIfConnectionAborted(m_ConnectStream.Connection, true);
                bytesRead = await base.ReadAsync(buffer, offset, count, cancellationToken).SuppressContextFlow <int>();

                if (WebSocketBase.LoggingEnabled)
                {
                    Logging.Dump(Logging.WebSockets, this, Methods.ReadAsync, buffer, offset, bytesRead);
                }
            }
            catch (Exception error)
            {
                if (s_CanHandleException(error))
                {
                    cancellationToken.ThrowIfCancellationRequested();
                }

                throw;
            }
            finally
            {
                cancellationTokenRegistration.Dispose();

                if (WebSocketBase.LoggingEnabled)
                {
                    Logging.Exit(Logging.WebSockets, this, Methods.ReadAsync, bytesRead);
                }
            }

            return(bytesRead);
        }
            internal Task <int> ReadAsyncCore(byte[] buffer, int offset, int count, CancellationToken cancellationToken,
                                              bool ignoreReadError)
            {
                if (WebSocketBase.LoggingEnabled)
                {
                    Logging.Enter(Logging.WebSockets, this, Methods.ReadAsyncCore,
                                  WebSocketHelpers.GetTraceMsgForParameters(offset, count, cancellationToken));
                }

                bool completedAsynchronously = false;

                m_IgnoreReadError = ignoreReadError;
                try
                {
                    cancellationToken.ThrowIfCancellationRequested();
#if DEBUG
                    // When using fast path only one outstanding read is permitted. By switching into opaque mode
                    // via IWebSocketStream.SwitchToOpaqueMode (see more detailed comments in interface definition)
                    // caller takes responsibility for enforcing this constraint.
                    Contract.Assert(Interlocked.Increment(ref m_OutstandingOperations.m_Reads) == 1,
                                    "Only one outstanding read allowed at any given time.");
#endif
                    WebSocketHelpers.ThrowIfConnectionAborted(m_InnerStream, true);
                    m_ReadTaskCompletionSource = new TaskCompletionSource <int>();
                    Contract.Assert(m_ReadEventArgs != null, "'m_ReadEventArgs' MUST NOT be NULL.");
                    m_ReadEventArgs.SetBuffer(buffer, offset, count);
                    Socket innerSocket;
                    if (ignoreReadError)
                    {
                        // The State of the WebSocket instance is already Closed at this point
                        // Skipping call to WebSocketBase.ThrowIfClosedOrAborted
                        innerSocket = GetInnerSocket(true);
                    }
                    else
                    {
                        innerSocket = InnerSocket;
                    }
                    completedAsynchronously = innerSocket.ReceiveAsync(m_ReadEventArgs);
                    if (!completedAsynchronously)
                    {
                        if (m_ReadEventArgs.SocketError != SocketError.Success)
                        {
                            if (!m_IgnoreReadError)
                            {
                                throw new SocketException(m_ReadEventArgs.SocketError);
                            }
                            else
                            {
                                return(Task.FromResult <int>(0));
                            }
                        }

                        return(Task.FromResult <int>(m_ReadEventArgs.BytesTransferred));
                    }

                    return(m_ReadTaskCompletionSource.Task);
                }
                finally
                {
                    if (WebSocketBase.LoggingEnabled)
                    {
                        Logging.Exit(Logging.WebSockets, this, Methods.ReadAsyncCore, completedAsynchronously);
                    }
                }
            }