private Task <bool> InternalReceiveAsync(ArraySegment <byte> buffer) { bool receiveOperationAlreadyPending = false; if (_operation.PendingReadOperation == false) { lock (_operation.Lock) { if (_operation.PendingReadOperation == false) { _operation.CheckValidState(s_validReceiveStates); // Prevent continuations from running on the same thread as the callback to prevent re-entrance deadlocks _operation.TcsReceive = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); _operation.PendingReadOperation = true; uint bytesRead = 0; Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE winHttpBufferType = 0; uint status = Interop.WinHttp.WinHttpWebSocketReceive( _operation.WebSocketHandle, Marshal.UnsafeAddrOfPinnedArrayElement(buffer.Array, buffer.Offset), (uint)buffer.Count, out bytesRead, // Unused in async mode: ignore. out winHttpBufferType); // Unused in async mode: ignore. if (Interop.WinHttp.ERROR_SUCCESS != status) { throw WinHttpException.CreateExceptionUsingError((int)status); } } else { receiveOperationAlreadyPending = true; } } } else { receiveOperationAlreadyPending = true; } if (receiveOperationAlreadyPending) { var exception = new InvalidOperationException( SR.Format(SR.net_Websockets_AlreadyOneOutstandingOperation, "ReceiveAsync")); _operation.TcsReceive.TrySetException(exception); Abort(); } return(_operation.TcsReceive.Task); }
private Task <bool> InternalReceiveAsync(Memory <byte> pinnedBuffer) { bool receiveOperationAlreadyPending = false; if (_operation.PendingReadOperation == false) { lock (_operation.Lock) { if (_operation.PendingReadOperation == false) { _operation.CheckValidState(s_validReceiveStates); // Prevent continuations from running on the same thread as the callback to prevent re-entrance deadlocks _operation.TcsReceive = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); _operation.PendingReadOperation = true; uint bytesRead = 0; Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE winHttpBufferType = 0; IntPtr pinnedBufferPtr; unsafe { fixed(byte *p = &pinnedBuffer.Span.DangerousGetPinnableReference()) { pinnedBufferPtr = (IntPtr)p; } } uint status = Interop.WinHttp.WinHttpWebSocketReceive( _operation.WebSocketHandle, pinnedBufferPtr, (uint)pinnedBuffer.Length, out bytesRead, // Unused in async mode: ignore. out winHttpBufferType); // Unused in async mode: ignore. if (Interop.WinHttp.ERROR_SUCCESS != status) { throw WinHttpException.CreateExceptionUsingError((int)status); } } else { receiveOperationAlreadyPending = true; } } } else { receiveOperationAlreadyPending = true; } if (receiveOperationAlreadyPending) { var exception = new InvalidOperationException( SR.Format(SR.net_Websockets_AlreadyOneOutstandingOperation, "ReceiveAsync")); _operation.TcsReceive.TrySetException(exception); Abort(); } return(_operation.TcsReceive.Task); }