System.Net.WebSockets.ManagedWebSocket.SendFrameAsync C# (CSharp) Method

SendFrameAsync() private method

Sends a websocket frame to the network.
private SendFrameAsync ( MessageOpcode opcode, bool endOfMessage, ArraySegment payloadBuffer, CancellationToken cancellationToken ) : Task
opcode MessageOpcode The opcode for the message.
endOfMessage bool The value of the FIN bit for the message.
payloadBuffer ArraySegment The buffer containing the payload data fro the message.
cancellationToken System.Threading.CancellationToken The CancellationToken to use to cancel the websocket.
return Task
        private Task SendFrameAsync(MessageOpcode opcode, bool endOfMessage, ArraySegment<byte> payloadBuffer, CancellationToken cancellationToken)
        {
            // TODO: #4900 SendFrameAsync should in theory typically complete synchronously, making it fast and allocation free.
            // However, due to #4900, it almost always yields, resulting in all of the allocations involved in an async method
            // yielding, e.g. the boxed state machine, the Action delegate, the MoveNextRunner, and the resulting Task, plus it's
            // common that the awaited operation completes so fast after the await that we may end up allocating an AwaitTaskContinuation
            // inside of the TaskAwaiter.  Since SendFrameAsync is such a core code path, until that can be fixed, we put some
            // optimizations in place to avoid a few of those expenses, at the expense of more complicated code; for the common case,
            // this code has fewer than half the number and size of allocations.  If/when that issue is fixed, this method should be deleted
            // and replaced by SendFrameFallbackAsync, which is the same logic but in a much more easily understand flow.

            // If a cancelable cancellation token was provided, that would require registering with it, which means more state we have to
            // pass around (the CancellationTokenRegistration), so if it is cancelable, just immediately go to the fallback path.
            // Similarly, it should be rare that there are multiple outstanding calls to SendFrameAsync, but if there are, again
            // fall back to the fallback path.
            return cancellationToken.CanBeCanceled || !_sendFrameAsyncLock.Wait(0) ?
                SendFrameFallbackAsync(opcode, endOfMessage, payloadBuffer, cancellationToken) :
                SendFrameLockAcquiredNonCancelableAsync(opcode, endOfMessage, payloadBuffer);
        }