System.Net.WebSockets.WebSocketBase.SendAsyncCore C# (CSharp) Method

SendAsyncCore() private method

private SendAsyncCore ( ArraySegment buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken ) : Task
buffer ArraySegment
messageType WebSocketMessageType
endOfMessage bool
cancellationToken System.Threading.CancellationToken
return Task
        private async Task SendAsyncCore(ArraySegment<byte> buffer,
            WebSocketMessageType messageType,
            bool endOfMessage,
            CancellationToken cancellationToken)
        {
            Debug.Assert(messageType == WebSocketMessageType.Binary || messageType == WebSocketMessageType.Text,
                "'messageType' MUST be either 'WebSocketMessageType.Binary' or 'WebSocketMessageType.Text'.");
            Debug.Assert(buffer != null);

            string inputParameter = string.Empty;
            if (NetEventSource.IsEnabled)
            {
                inputParameter = string.Format(CultureInfo.InvariantCulture,
                    "messageType: {0}, endOfMessage: {1}",
                    messageType,
                    endOfMessage);
                NetEventSource.Enter(this, inputParameter);
            }

            try
            {
                ThrowIfPendingException();
                ThrowIfDisposed();
                ThrowOnInvalidState(State, WebSocketState.Open, WebSocketState.CloseReceived);
                bool ownsCancellationTokenSource = false;
                CancellationToken linkedCancellationToken = CancellationToken.None;

                try
                {
                    while (!(ownsCancellationTokenSource = _sendOutstandingOperationHelper.TryStartOperation(cancellationToken, out linkedCancellationToken)))
                    {
                        Task keepAliveTask;

                        lock (SessionHandle)
                        {
                            keepAliveTask = _keepAliveTask;

                            if (keepAliveTask == null)
                            {
                                // Check whether there is still another outstanding send operation
                                // Potentially the keepAlive operation has completed before this thread
                                // was able to enter the SessionHandle-lock. 
                                _sendOutstandingOperationHelper.CompleteOperation(ownsCancellationTokenSource);
                                if (ownsCancellationTokenSource = _sendOutstandingOperationHelper.TryStartOperation(cancellationToken, out linkedCancellationToken))
                                {
                                    break;
                                }
                                else
                                {
                                    throw new InvalidOperationException(
                                        SR.Format(SR.net_Websockets_AlreadyOneOutstandingOperation, nameof(SendAsync)));
                                }
                            }
                        }

                        await keepAliveTask.SuppressContextFlow();
                        ThrowIfPendingException();

                        _sendOutstandingOperationHelper.CompleteOperation(ownsCancellationTokenSource);
                    }

                    if (NetEventSource.IsEnabled && buffer.Count > 0)
                    {
                        NetEventSource.DumpBuffer(this, buffer.Array, buffer.Offset, buffer.Count);
                    }

                    int position = buffer.Offset;

                    EnsureSendOperation();
                    _sendOperation.BufferType = GetBufferType(messageType, endOfMessage);
                    await _sendOperation.Process(buffer, linkedCancellationToken).SuppressContextFlow();
                }
                catch (Exception exception)
                {
                    bool aborted = linkedCancellationToken.IsCancellationRequested;
                    Abort();
                    ThrowIfConvertibleException(nameof(SendAsync), exception, cancellationToken, aborted);
                    throw;
                }
                finally
                {
                    _sendOutstandingOperationHelper.CompleteOperation(ownsCancellationTokenSource);
                }
            }
            finally
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Exit(this, inputParameter);
                }
            }
        }