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); } } }