public override ValueTask <ValueWebSocketReceiveResult> ReceiveAsync(Memory <byte> buffer, CancellationToken cancellationToken)
        {
            try
            {
                WebSocketValidate.ThrowIfInvalidState(_state, _disposed, s_validReceiveStates);

                Debug.Assert(!Monitor.IsEntered(StateUpdateLock), $"{nameof(StateUpdateLock)} must never be held when acquiring {nameof(ReceiveAsyncLock)}");
                lock (ReceiveAsyncLock) // synchronize with receives in CloseAsync
                {
                    ThrowIfOperationInProgress(_lastReceiveAsync.IsCompleted);

                    ValueTask <ValueWebSocketReceiveResult> receiveValueTask = ReceiveAsyncPrivate <ValueWebSocketReceiveResultGetter, ValueWebSocketReceiveResult>(buffer, cancellationToken);
                    if (receiveValueTask.IsCompletedSuccessfully)
                    {
                        _lastReceiveAsync = receiveValueTask.Result.MessageType == WebSocketMessageType.Close ? s_cachedCloseTask : Task.CompletedTask;
                        return(receiveValueTask);
                    }

                    // We need to both store the last receive task and return it, but we can't do that with a ValueTask,
                    // as that could result in consuming it multiple times.  Instead, we use AsTask to consume it just once,
                    // and then store that Task and return a new ValueTask that wraps it. (It would be nice in the future
                    // to avoid this AsTask as well; currently it's used both for error detection and as part of close tracking.)
                    Task <ValueWebSocketReceiveResult> receiveTask = receiveValueTask.AsTask();
                    _lastReceiveAsync = receiveTask;
                    return(new ValueTask <ValueWebSocketReceiveResult>(receiveTask));
                }
            }
            catch (Exception exc)
            {
                return(ValueTask.FromException <ValueWebSocketReceiveResult>(exc));
            }
        }
 public void InterlockedCheckValidStates(WebSocketState[] validStates)
 {
     lock (_lock)
     {
         WebSocketValidate.ThrowIfInvalidState(_state, _disposed, validStates);
     }
 }
        public override ValueTask <ValueWebSocketReceiveResult> ReceiveAsync(Memory <byte> buffer, CancellationToken cancellationToken)
        {
            try
            {
                WebSocketValidate.ThrowIfInvalidState(_state, _disposed, s_validReceiveStates);

                Debug.Assert(!Monitor.IsEntered(StateUpdateLock), $"{nameof(StateUpdateLock)} must never be held when acquiring {nameof(ReceiveAsyncLock)}");
                lock (ReceiveAsyncLock) // synchronize with receives in CloseAsync
                {
                    ThrowIfOperationInProgress(_lastReceiveAsync.IsCompleted);
                    ValueTask <ValueWebSocketReceiveResult> t = ReceiveAsyncPrivate <ValueWebSocketReceiveResultGetter, ValueWebSocketReceiveResult>(buffer, cancellationToken);

                    // WARNING: This code is only valid because ReceiveAsyncPrivate returns a ValueTask that wraps a T or a Task.
                    // If that ever changes where ReceiveAsyncPrivate could wrap an IValueTaskSource, this must also change.
                    _lastReceiveAsync =
                        t.IsCompletedSuccessfully ? (t.Result.MessageType == WebSocketMessageType.Close ? s_cachedCloseTask : Task.CompletedTask) :
                        t.AsTask();
                    return(t);
                }
            }
            catch (Exception exc)
            {
                return(new ValueTask <ValueWebSocketReceiveResult>(Task.FromException <ValueWebSocketReceiveResult>(exc)));
            }
        }
 // Must be called with Lock taken.
 public void CheckValidState(WebSocketState[] validStates)
 {
     WebSocketValidate.ThrowIfInvalidState(_state, _disposed, validStates);
 }