// 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) ?
- new ValueTask(SendFrameFallbackAsync(opcode, endOfMessage, payloadBuffer, cancellationToken)) :
+ SendFrameFallbackAsync(opcode, endOfMessage, payloadBuffer, cancellationToken) :
SendFrameLockAcquiredNonCancelableAsync(opcode, endOfMessage, payloadBuffer);
}
}
}
- return new ValueTask(WaitForWriteTaskAsync(writeTask));
+ return WaitForWriteTaskAsync(writeTask);
}
- private async Task WaitForWriteTaskAsync(ValueTask writeTask)
+ private async ValueTask WaitForWriteTaskAsync(ValueTask writeTask)
{
try
{
}
}
- private async Task SendFrameFallbackAsync(MessageOpcode opcode, bool endOfMessage, ReadOnlyMemory<byte> payloadBuffer, CancellationToken cancellationToken)
+ private async ValueTask SendFrameFallbackAsync(MessageOpcode opcode, bool endOfMessage, ReadOnlyMemory<byte> payloadBuffer, CancellationToken cancellationToken)
{
await _sendFrameAsyncLock.WaitAsync(cancellationToken).ConfigureAwait(false);
try
/// <summary>Processes a received close message.</summary>
/// <param name="header">The message header.</param>
/// <returns>The received result message.</returns>
- private async Task HandleReceivedCloseAsync(MessageHeader header, CancellationToken cancellationToken)
+ private async ValueTask HandleReceivedCloseAsync(MessageHeader header, CancellationToken cancellationToken)
{
lock (StateUpdateLock)
{
}
/// <summary>Issues a read on the stream to wait for EOF.</summary>
- private async Task WaitForServerToCloseConnectionAsync(CancellationToken cancellationToken)
+ private async ValueTask WaitForServerToCloseConnectionAsync(CancellationToken cancellationToken)
{
// Per RFC 6455 7.1.1, try to let the server close the connection. We give it up to a second.
// We simply issue a read and don't care what we get back; we could validate that we don't get
/// <summary>Processes a received ping or pong message.</summary>
/// <param name="header">The message header.</param>
- private async Task HandleReceivedPingPongAsync(MessageHeader header, CancellationToken cancellationToken)
+ private async ValueTask HandleReceivedPingPongAsync(MessageHeader header, CancellationToken cancellationToken)
{
// Consume any (optional) payload associated with the ping/pong.
if (header.PayloadLength > 0 && _receiveBufferCount < header.PayloadLength)
/// <param name="closeStatus">The close status code to use.</param>
/// <param name="error">The error reason.</param>
/// <param name="innerException">An optional inner exception to include in the thrown exception.</param>
- private async Task CloseWithReceiveErrorAndThrowAsync(
+ private async ValueTask CloseWithReceiveErrorAndThrowAsync(
WebSocketCloseStatus closeStatus, WebSocketError error, Exception innerException = null)
{
// Close the connection if it hasn't already been closed
/// <param name="closeStatus">The close status to send.</param>
/// <param name="closeStatusDescription">The close status description to send.</param>
/// <param name="cancellationToken">The CancellationToken to use to cancel the websocket.</param>
- private async Task SendCloseFrameAsync(WebSocketCloseStatus closeStatus, string closeStatusDescription, CancellationToken cancellationToken)
+ private async ValueTask SendCloseFrameAsync(WebSocketCloseStatus closeStatus, string closeStatusDescription, CancellationToken cancellationToken)
{
// Close payload is two bytes containing the close status followed by a UTF8-encoding of the status description, if it exists.
_receiveBufferOffset += count;
}
- private async Task EnsureBufferContainsAsync(int minimumRequiredBytes, CancellationToken cancellationToken, bool throwOnPrematureClosure = true)
+ private async ValueTask EnsureBufferContainsAsync(int minimumRequiredBytes, CancellationToken cancellationToken, bool throwOnPrematureClosure = true)
{
Debug.Assert(minimumRequiredBytes <= _receiveBuffer.Length, $"Requested number of bytes {minimumRequiredBytes} must not exceed {_receiveBuffer.Length}");
EnsureNoActiveAsyncOperation();
EnsureNotDisposed();
- return new ValueTask(cancellationToken.IsCancellationRequested ?
- Task.FromCanceled<int>(cancellationToken) :
- WriteAsyncMemoryCore(buffer, cancellationToken));
+ return cancellationToken.IsCancellationRequested ?
+ new ValueTask(Task.FromCanceled<int>(cancellationToken)) :
+ WriteAsyncMemoryCore(buffer, cancellationToken);
}
- private async Task WriteAsyncMemoryCore(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken, bool isFinalBlock = false)
+ private async ValueTask WriteAsyncMemoryCore(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken, bool isFinalBlock = false)
{
AsyncOperationStarting();
try
}
}
- private async Task PurgeBuffersAsync()
+ private async ValueTask PurgeBuffersAsync()
{
// Same logic as PurgeBuffers, except with async counterparts.
EnsureNoActiveAsyncOperation();
EnsureNotDisposed();
- return new ValueTask(cancellationToken.IsCancellationRequested ?
- Task.FromCanceled<int>(cancellationToken) :
- WriteAsyncMemoryCore(buffer, cancellationToken));
+ return cancellationToken.IsCancellationRequested ?
+ new ValueTask(Task.FromCanceled<int>(cancellationToken)) :
+ WriteAsyncMemoryCore(buffer, cancellationToken);
}
- private async Task WriteAsyncMemoryCore(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
+ private async ValueTask WriteAsyncMemoryCore(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
{
AsyncOperationStarting();
try
/// <summary>
/// Writes the bytes that have already been deflated
/// </summary>
- private async Task WriteDeflaterOutputAsync(CancellationToken cancellationToken)
+ private async ValueTask WriteDeflaterOutputAsync(CancellationToken cancellationToken)
{
Debug.Assert(_deflater != null && _buffer != null);
while (!_deflater.NeedsInput())
SetRequestAuthenticationHeaderValue(request, new AuthenticationHeaderValue(BasicScheme, base64AuthString), isProxyAuth);
}
- private static async Task<bool> TrySetDigestAuthToken(HttpRequestMessage request, NetworkCredential credential, DigestResponse digestResponse, bool isProxyAuth)
+ private static async ValueTask<bool> TrySetDigestAuthToken(HttpRequestMessage request, NetworkCredential credential, DigestResponse digestResponse, bool isProxyAuth)
{
string parameter = await GetDigestTokenForCredential(credential, request, digestResponse).ConfigureAwait(false);
public override bool NeedsDrain => (_connection != null);
- public override async Task<bool> DrainAsync(int maxDrainBytes)
+ public override async ValueTask<bool> DrainAsync(int maxDrainBytes)
{
Debug.Assert(_connection != null);
// Don't write if nothing was given, especially since we don't want to accidentally send a 0 chunk,
// which would indicate end of body. Instead, just ensure no content is stuck in the buffer.
connection.FlushAsync() :
- new ValueTask(WriteChunkAsync(connection, buffer));
+ WriteChunkAsync(connection, buffer);
return task;
- static async Task WriteChunkAsync(HttpConnection connection, ReadOnlyMemory<byte> buffer)
+ static async ValueTask WriteChunkAsync(HttpConnection connection, ReadOnlyMemory<byte> buffer)
{
// Write chunk length in hex followed by \r\n
await connection.WriteHexInt32Async(buffer.Length).ConfigureAwait(false);
}
}
- public override async Task FinishAsync()
+ public override async ValueTask FinishAsync()
{
// Send 0 byte chunk to indicate end, then final CrLf
HttpConnection connection = GetConnectionOrThrow();
public override bool NeedsDrain => (_connection != null);
- public override async Task<bool> DrainAsync(int maxDrainBytes)
+ public override async ValueTask<bool> DrainAsync(int maxDrainBytes)
{
Debug.Assert(_connection != null);
Debug.Assert(_contentBytesRemaining > 0);
// that are still buffered.
HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);
- return new ValueTask(connection.WriteAsync(buffer));
+ return connection.WriteAsync(buffer);
}
- public override Task FinishAsync()
+ public override ValueTask FinishAsync()
{
_connection = null;
- return Task.CompletedTask;
+ return default;
}
}
}
var waiter = new Waiter { Amount = amount };
(_waiters ??= new Queue<Waiter>()).Enqueue(waiter);
- return new ValueTask<int>(cancellationToken.CanBeCanceled ?
- waiter.WaitWithCancellationAsync(cancellationToken) :
- waiter.Task);
+ return cancellationToken.CanBeCanceled ?
+ waiter.WaitWithCancellationAsync(cancellationToken) :
+ new ValueTask<int>(waiter.Task);
}
}
private object SyncObject => _httpStreams;
- public async Task SetupAsync()
+ public async ValueTask SetupAsync()
{
_outgoingBuffer.EnsureAvailableSpace(s_http2ConnectionPreface.Length +
FrameHeader.Size + (FrameHeader.SettingLength * 2) +
_ = ProcessIncomingFramesAsync();
}
- private async Task EnsureIncomingBytesAsync(int minReadBytes)
+ private async ValueTask EnsureIncomingBytesAsync(int minReadBytes)
{
if (NetEventSource.IsEnabled) Trace($"{nameof(minReadBytes)}={minReadBytes}");
if (_incomingBuffer.ActiveLength >= minReadBytes)
}
}
- private async Task ProcessHeadersFrame(FrameHeader frameHeader)
+ private async ValueTask ProcessHeadersFrame(FrameHeader frameHeader)
{
if (NetEventSource.IsEnabled) Trace($"{frameHeader}");
Debug.Assert(frameHeader.Type == FrameType.Headers);
}
}
- private async Task AcquireWriteLockAsync(CancellationToken cancellationToken)
+ private async ValueTask AcquireWriteLockAsync(CancellationToken cancellationToken)
{
Task acquireLockTask = _writerLock.WaitAsync(cancellationToken);
if (!acquireLockTask.IsCompletedSuccessfully)
// We can either get 100 response from server and send body
// or we may exceed timeout and send request body anyway.
// If we get response status >= 300, we will not send the request body.
- public async Task<bool> WaitFor100ContinueAsync(CancellationToken cancellationToken)
+ public async ValueTask<bool> WaitFor100ContinueAsync(CancellationToken cancellationToken)
{
Debug.Assert(_request.Content != null);
if (NetEventSource.IsEnabled) Trace($"Waiting to send request body content for 100-Continue.");
}
}
- private async Task SendDataAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
+ private async ValueTask SendDataAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
{
ReadOnlyMemory<byte> remaining = buffer;
// if it is cancelable, then register for the cancellation callback, allocate a task for the asynchronously
// completing case, etc.
return cancellationToken.CanBeCanceled ?
- new ValueTask(GetCancelableWaiterTask(cancellationToken)) :
+ GetCancelableWaiterTask(cancellationToken) :
new ValueTask(this, _waitSource.Version);
}
- private async Task GetCancelableWaiterTask(CancellationToken cancellationToken)
+ private async ValueTask GetCancelableWaiterTask(CancellationToken cancellationToken)
{
using (cancellationToken.UnsafeRegister(s =>
{
return new ValueTask(Task.FromException(new ObjectDisposedException(nameof(Http2WriteStream))));
}
- return new ValueTask(http2Stream.SendDataAsync(buffer, cancellationToken));
+ return http2Stream.SendDataAsync(buffer, cancellationToken);
}
public override Task FlushAsync(CancellationToken cancellationToken)
_readOffset += bytesToConsume;
}
- private async Task WriteHeadersAsync(HttpHeaders headers, string cookiesFromContainer)
+ private async ValueTask WriteHeadersAsync(HttpHeaders headers, string cookiesFromContainer)
{
if (headers.HeaderStore != null)
{
}
}
- private async Task WriteHostHeaderAsync(Uri uri)
+ private async ValueTask WriteHostHeaderAsync(Uri uri)
{
await WriteBytesAsync(KnownHeaders.Host.AsciiBytesWithColonSpace).ConfigureAwait(false);
private static bool IsLineEmpty(ArraySegment<byte> line) => line.Count == 0;
- private async Task SendRequestContentAsync(HttpRequestMessage request, HttpContentWriteStream stream, CancellationToken cancellationToken)
+ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, HttpContentWriteStream stream, CancellationToken cancellationToken)
{
// Now that we're sending content, prohibit retries on this connection.
_canRetry = false;
_writeOffset += source.Length;
}
- private async Task WriteAsync(ReadOnlyMemory<byte> source)
+ private async ValueTask WriteAsync(ReadOnlyMemory<byte> source)
{
int remaining = _writeBuffer.Length - _writeOffset;
// There's data in the write buffer and the data we're writing doesn't fit after it.
// Do two writes, one to flush the buffer and then another to write the supplied content.
- return new ValueTask(FlushThenWriteWithoutBufferingAsync(source));
+ return FlushThenWriteWithoutBufferingAsync(source);
}
- private async Task FlushThenWriteWithoutBufferingAsync(ReadOnlyMemory<byte> source)
+ private async ValueTask FlushThenWriteWithoutBufferingAsync(ReadOnlyMemory<byte> source)
{
await FlushAsync().ConfigureAwait(false);
await WriteToStreamAsync(source).ConfigureAwait(false);
}
// Throws IOException on EOF. This is only called when we expect more data.
- private async Task FillAsync()
+ private async ValueTask FillAsync()
{
Debug.Assert(_readAheadTask == null);
return bytesToCopy;
}
- private async Task CopyFromBufferAsync(Stream destination, int count, CancellationToken cancellationToken)
+ private async ValueTask CopyFromBufferAsync(Stream destination, int count, CancellationToken cancellationToken)
{
Debug.Assert(count <= _readLength - _readOffset);
}
}
- public async Task DrainResponseAsync(HttpResponseMessage response)
+ public async ValueTask DrainResponseAsync(HttpResponseMessage response)
{
Debug.Assert(_inUse);
// We are at the connection limit. Wait for an available connection or connection count (indicated by null).
if (NetEventSource.IsEnabled) Trace("Connection limit reached, waiting for available connection.");
- return new ValueTask<HttpConnection>(waiter.WaitWithCancellationAsync(cancellationToken));
+ return waiter.WaitWithCancellationAsync(cancellationToken);
}
private async ValueTask<(HttpConnectionBase connection, bool isNewConnection, HttpResponseMessage failureResponse)>
protected bool IsDisposed => _disposed == 1;
- public virtual Task<bool> DrainAsync(int maxDrainBytes)
+ public virtual ValueTask<bool> DrainAsync(int maxDrainBytes)
{
Debug.Fail($"DrainAsync should not be called for this response stream: {GetType()}");
- return Task.FromResult(false);
+ return new ValueTask<bool>(false);
}
protected override void Dispose(bool disposing)
public sealed override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) => throw new NotSupportedException();
- public abstract Task FinishAsync();
+ public abstract ValueTask FinishAsync();
}
}
}
TrySetCanceled(_cancellationToken);
}
- public async Task<T> WaitWithCancellationAsync(CancellationToken cancellationToken)
+ public async ValueTask<T> WaitWithCancellationAsync(CancellationToken cancellationToken)
{
_cancellationToken = cancellationToken;
using (cancellationToken.UnsafeRegister(s => ((TaskCompletionSourceWithCancellation<T>)s).OnCancellation(), this))
}
}
- private async Task WriteAsyncChunked<TWriteAdapter>(TWriteAdapter writeAdapter, ReadOnlyMemory<byte> buffer)
+ private async ValueTask WriteAsyncChunked<TWriteAdapter>(TWriteAdapter writeAdapter, ReadOnlyMemory<byte> buffer)
where TWriteAdapter : struct, ISslWriteAdapter
{
do
int chunkBytes = Math.Min(buffer.Length, MaxDataSize);
await WriteSingleChunk(writeAdapter, buffer.Slice(0, chunkBytes)).ConfigureAwait(false);
buffer = buffer.Slice(chunkBytes);
-
} while (buffer.Length != 0);
}
if (!ioSlot.IsCompletedSuccessfully)
{
// Operation is async and has been queued, return.
- return new ValueTask(WaitForWriteIOSlot(writeAdapter, ioSlot, buffer));
+ return WaitForWriteIOSlot(writeAdapter, ioSlot, buffer);
}
byte[] rentedBuffer = ArrayPool<byte>.Shared.Rent(buffer.Length + FrameOverhead);
}
else
{
- return new ValueTask(CompleteAsync(t, rentedBuffer));
+ return CompleteAsync(t, rentedBuffer);
}
- async Task WaitForWriteIOSlot(TWriteAdapter wAdapter, Task lockTask, ReadOnlyMemory<byte> buff)
+ async ValueTask WaitForWriteIOSlot(TWriteAdapter wAdapter, Task lockTask, ReadOnlyMemory<byte> buff)
{
await lockTask.ConfigureAwait(false);
await WriteSingleChunk(wAdapter, buff).ConfigureAwait(false);
}
- async Task CompleteAsync(ValueTask writeTask, byte[] bufferToReturn)
+ async ValueTask CompleteAsync(ValueTask writeTask, byte[] bufferToReturn)
{
try
{
}
}
- private async Task WriteAsyncInternal<TWriteAdapter>(TWriteAdapter writeAdapter, ReadOnlyMemory<byte> buffer)
+ private async ValueTask WriteAsyncInternal<TWriteAdapter>(TWriteAdapter writeAdapter, ReadOnlyMemory<byte> buffer)
where TWriteAdapter : struct, ISslWriteAdapter
{
ThrowIfExceptionalOrNotAuthenticatedOrShutdown();
{
ValueTask t = buffer.Length < MaxDataSize ?
WriteSingleChunk(writeAdapter, buffer) :
- new ValueTask(WriteAsyncChunked(writeAdapter, buffer));
+ WriteAsyncChunked(writeAdapter, buffer);
await t.ConfigureAwait(false);
}
catch (Exception e)
ValidateParameters(buffer, offset, count);
SslWriteSync writeAdapter = new SslWriteSync(this);
- WriteAsyncInternal(writeAdapter, new ReadOnlyMemory<byte>(buffer, offset, count)).GetAwaiter().GetResult();
+ WriteAsyncInternal(writeAdapter, new ReadOnlyMemory<byte>(buffer, offset, count)).AsTask().GetAwaiter().GetResult();
}
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
{
ThrowIfExceptionalOrNotAuthenticated();
SslWriteAsync writeAdapter = new SslWriteAsync(this, cancellationToken);
- return new ValueTask(WriteAsyncInternal(writeAdapter, buffer));
+ return WriteAsyncInternal(writeAdapter, buffer);
}
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
}
- private Task WriteAsyncInternal<TWriteAdapter>(TWriteAdapter writeAdapter, ReadOnlyMemory<byte> buffer)
+ private ValueTask WriteAsyncInternal<TWriteAdapter>(TWriteAdapter writeAdapter, ReadOnlyMemory<byte> buffer)
where TWriteAdapter : struct, ISslWriteAdapter => default;
private ValueTask<int> ReadAsyncInternal<TReadAdapter>(TReadAdapter adapter, Memory<byte> buffer) => default;
}
public virtual ValueTask SendAsync(ReadOnlyMemory<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) =>
- new ValueTask(MemoryMarshal.TryGetArray(buffer, out ArraySegment<byte> arraySegment) ?
- SendAsync(arraySegment, messageType, endOfMessage, cancellationToken) :
- SendWithArrayPoolAsync(buffer, messageType, endOfMessage, cancellationToken));
+ MemoryMarshal.TryGetArray(buffer, out ArraySegment<byte> arraySegment) ?
+ new ValueTask(SendAsync(arraySegment, messageType, endOfMessage, cancellationToken)) :
+ SendWithArrayPoolAsync(buffer, messageType, endOfMessage, cancellationToken);
- private async Task SendWithArrayPoolAsync(
+ private async ValueTask SendWithArrayPoolAsync(
ReadOnlyMemory<byte> buffer,
WebSocketMessageType messageType,
bool endOfMessage,
_stream.Flush();
}
- private async Task FlushWriteAsync(CancellationToken cancellationToken)
+ private async ValueTask FlushWriteAsync(CancellationToken cancellationToken)
{
Debug.Assert(_stream != null);
Debug.Assert(_readPos == 0 && _readLen == 0,
}
// Delegate to the async implementation.
- return new ValueTask(WriteToUnderlyingStreamAsync(buffer, cancellationToken, semaphoreLockTask));
+ return WriteToUnderlyingStreamAsync(buffer, cancellationToken, semaphoreLockTask);
}
/// <summary>BufferedStream should be as thin a wrapper as possible. We want WriteAsync to delegate to
/// in terms of the other. This allows BufferedStream to affect the semantics of the stream it wraps as
/// little as possible.
/// </summary>
- private async Task WriteToUnderlyingStreamAsync(
+ private async ValueTask WriteToUnderlyingStreamAsync(
ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken, Task semaphoreLockTask)
{
Debug.Assert(_stream != null);
// byte[] ciphertext = ms.ToArray();
// cs.Close();
public void FlushFinalBlock() =>
- FlushFinalBlockAsync(useAsync: false).GetAwaiter().GetResult();
+ FlushFinalBlockAsync(useAsync: false).AsTask().GetAwaiter().GetResult();
- private async Task FlushFinalBlockAsync(bool useAsync)
+ private async ValueTask FlushFinalBlockAsync(bool useAsync)
{
if (_finalBlockTransformed)
throw new NotSupportedException(SR.Cryptography_CryptoStream_FlushFinalBlockTwice);
public override void Write(byte[] buffer, int offset, int count)
{
CheckWriteArguments(buffer, offset, count);
- WriteAsyncCore(buffer, offset, count, default(CancellationToken), useAsync: false).GetAwaiter().GetResult();
+ WriteAsyncCore(buffer, offset, count, default(CancellationToken), useAsync: false).AsTask().GetAwaiter().GetResult();
}
private void CheckWriteArguments(byte[] buffer, int offset, int count)
throw new ArgumentException(SR.Argument_InvalidOffLen);
}
- private async Task WriteAsyncCore(byte[] buffer, int offset, int count, CancellationToken cancellationToken, bool useAsync)
+ private async ValueTask WriteAsyncCore(byte[] buffer, int offset, int count, CancellationToken cancellationToken, bool useAsync)
{
// write <= count bytes to the output stream, transforming as we go.
// Basic idea: using bytes in the _InputBuffer first, make whole blocks,
return
cancellationToken.IsCancellationRequested ? new ValueTask(Task.FromCanceled<T>(cancellationToken)) :
TryWrite(item) ? default :
- new ValueTask(WriteAsyncCore(item, cancellationToken));
+ WriteAsyncCore(item, cancellationToken);
}
catch (Exception e)
{
}
}
- private async Task WriteAsyncCore(T innerItem, CancellationToken ct)
+ private async ValueTask WriteAsyncCore(T innerItem, CancellationToken ct)
{
while (await WaitToWriteAsync(ct).ConfigureAwait(false))
{