Change some internal async Task methods to be async ValueTask (dotnet/corefx#40527)
authorStephen Toub <stoub@microsoft.com>
Thu, 10 Oct 2019 10:04:01 +0000 (06:04 -0400)
committerGitHub <noreply@github.com>
Thu, 10 Oct 2019 10:04:01 +0000 (06:04 -0400)
We have some internal and private `async Task` methods that are only ever `await`ed.  Today there's no benefit to making them `async ValueTask` methods, so we've kept them as `async Task`.  However, if we end up changing the implementation of `async ValueTask` to pool underlying objects, there becomes a potential benefit to using `async ValueTask` for these instead of `async Task`.  This PR changes those in a variety of libraries where we care more about performance and allocations.  There are likely a few more methods we'd want to convert based on profiling, but I believe this represents the bulk of them.

Commit migrated from https://github.com/dotnet/corefx/commit/97d9fb9d6c7e1d50f527e290ef8e18767dbc6bbf

23 files changed:
src/libraries/Common/src/System/Net/WebSockets/ManagedWebSocket.cs
src/libraries/System.IO.Compression.Brotli/src/System/IO/Compression/enc/BrotliStream.Compress.cs
src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/DeflateStream.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingWriteStream.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthReadStream.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthWriteStream.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditManager.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentReadStream.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentWriteStream.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/TaskCompletionSourceWithCancellation.cs
src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs
src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs
src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeSslStream.Implementation.cs
src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/WebSocket.cs
src/libraries/System.Runtime.Extensions/src/System/IO/BufferedStream.cs
src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/CryptoStream.cs
src/libraries/System.Threading.Channels/src/System/Threading/Channels/ChannelWriter.cs

index 4dae39d..a900ed9 100644 (file)
@@ -370,7 +370,7 @@ namespace System.Net.WebSockets
             // 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);
         }
 
@@ -421,10 +421,10 @@ namespace System.Net.WebSockets
                 }
             }
 
-            return new ValueTask(WaitForWriteTaskAsync(writeTask));
+            return WaitForWriteTaskAsync(writeTask);
         }
 
-        private async Task WaitForWriteTaskAsync(ValueTask writeTask)
+        private async ValueTask WaitForWriteTaskAsync(ValueTask writeTask)
         {
             try
             {
@@ -443,7 +443,7 @@ namespace System.Net.WebSockets
             }
         }
 
-        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
@@ -781,7 +781,7 @@ namespace System.Net.WebSockets
         /// <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)
             {
@@ -848,7 +848,7 @@ namespace System.Net.WebSockets
         }
 
         /// <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
@@ -876,7 +876,7 @@ namespace System.Net.WebSockets
 
         /// <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)
@@ -949,7 +949,7 @@ namespace System.Net.WebSockets
         /// <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
@@ -1132,7 +1132,7 @@ namespace System.Net.WebSockets
         /// <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.
 
@@ -1193,7 +1193,7 @@ namespace System.Net.WebSockets
             _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}");
 
index dd46856..b800268 100644 (file)
@@ -76,12 +76,12 @@ namespace System.IO.Compression
             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
index 9416b37..8af9471 100644 (file)
@@ -631,7 +631,7 @@ namespace System.IO.Compression
             }
         }
 
-        private async Task PurgeBuffersAsync()
+        private async ValueTask PurgeBuffersAsync()
         {
             // Same logic as PurgeBuffers, except with async counterparts.
 
@@ -809,12 +809,12 @@ namespace System.IO.Compression
             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
@@ -838,7 +838,7 @@ namespace System.IO.Compression
         /// <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())
index c310a4d..67b7df5 100644 (file)
@@ -184,7 +184,7 @@ namespace System.Net.Http
             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);
 
index c526c2f..d28f3d2 100644 (file)
@@ -429,7 +429,7 @@ namespace System.Net.Http
 
             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);
 
index 11f37ce..0f2f5e1 100644 (file)
@@ -31,11 +31,11 @@ namespace System.Net.Http
                     // 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);
@@ -47,7 +47,7 @@ namespace System.Net.Http
                 }
             }
 
-            public override async Task FinishAsync()
+            public override async ValueTask FinishAsync()
             {
                 // Send 0 byte chunk to indicate end, then final CrLf
                 HttpConnection connection = GetConnectionOrThrow();
index 00345da..7aba584 100644 (file)
@@ -191,7 +191,7 @@ namespace System.Net.Http
 
             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);
index 4804427..393271e 100644 (file)
@@ -23,13 +23,13 @@ namespace System.Net.Http
                 // 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;
             }
         }
     }
index 6337f64..f1bbf34 100644 (file)
@@ -64,9 +64,9 @@ namespace System.Net.Http
                 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);
             }
         }
 
index e73667b..2f1e6c1 100644 (file)
@@ -127,7 +127,7 @@ namespace System.Net.Http
 
         private object SyncObject => _httpStreams;
 
-        public async Task SetupAsync()
+        public async ValueTask SetupAsync()
         {
             _outgoingBuffer.EnsureAvailableSpace(s_http2ConnectionPreface.Length +
                 FrameHeader.Size + (FrameHeader.SettingLength * 2) +
@@ -165,7 +165,7 @@ namespace System.Net.Http
             _ = ProcessIncomingFramesAsync();
         }
 
-        private async Task EnsureIncomingBytesAsync(int minReadBytes)
+        private async ValueTask EnsureIncomingBytesAsync(int minReadBytes)
         {
             if (NetEventSource.IsEnabled) Trace($"{nameof(minReadBytes)}={minReadBytes}");
             if (_incomingBuffer.ActiveLength >= minReadBytes)
@@ -321,7 +321,7 @@ namespace System.Net.Http
             }
         }
 
-        private async Task ProcessHeadersFrame(FrameHeader frameHeader)
+        private async ValueTask ProcessHeadersFrame(FrameHeader frameHeader)
         {
             if (NetEventSource.IsEnabled) Trace($"{frameHeader}");
             Debug.Assert(frameHeader.Type == FrameType.Headers);
@@ -783,7 +783,7 @@ namespace System.Net.Http
             }
         }
 
-        private async Task AcquireWriteLockAsync(CancellationToken cancellationToken)
+        private async ValueTask AcquireWriteLockAsync(CancellationToken cancellationToken)
         {
             Task acquireLockTask = _writerLock.WaitAsync(cancellationToken);
             if (!acquireLockTask.IsCompletedSuccessfully)
index 06a4e81..f05b316 100644 (file)
@@ -269,7 +269,7 @@ namespace System.Net.Http
             // 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.");
@@ -969,7 +969,7 @@ namespace System.Net.Http
                 }
             }
 
-            private async Task SendDataAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
+            private async ValueTask SendDataAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
             {
                 ReadOnlyMemory<byte> remaining = buffer;
 
@@ -1047,11 +1047,11 @@ namespace System.Net.Http
                 // 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 =>
                 {
@@ -1213,7 +1213,7 @@ namespace System.Net.Http
                         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)
index 438903c..1fed738 100644 (file)
@@ -217,7 +217,7 @@ namespace System.Net.Http
             _readOffset += bytesToConsume;
         }
 
-        private async Task WriteHeadersAsync(HttpHeaders headers, string cookiesFromContainer)
+        private async ValueTask WriteHeadersAsync(HttpHeaders headers, string cookiesFromContainer)
         {
             if (headers.HeaderStore != null)
             {
@@ -278,7 +278,7 @@ namespace System.Net.Http
             }
         }
 
-        private async Task WriteHostHeaderAsync(Uri uri)
+        private async ValueTask WriteHostHeaderAsync(Uri uri)
         {
             await WriteBytesAsync(KnownHeaders.Host.AsciiBytesWithColonSpace).ConfigureAwait(false);
 
@@ -773,7 +773,7 @@ namespace System.Net.Http
 
         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;
@@ -986,7 +986,7 @@ namespace System.Net.Http
             _writeOffset += source.Length;
         }
 
-        private async Task WriteAsync(ReadOnlyMemory<byte> source)
+        private async ValueTask WriteAsync(ReadOnlyMemory<byte> source)
         {
             int remaining = _writeBuffer.Length - _writeOffset;
 
@@ -1063,10 +1063,10 @@ namespace System.Net.Http
 
             // 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);
@@ -1405,7 +1405,7 @@ namespace System.Net.Http
         }
 
         // 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);
 
@@ -1598,7 +1598,7 @@ namespace System.Net.Http
             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);
 
@@ -1768,7 +1768,7 @@ namespace System.Net.Http
             }
         }
 
-        public async Task DrainResponseAsync(HttpResponseMessage response)
+        public async ValueTask DrainResponseAsync(HttpResponseMessage response)
         {
             Debug.Assert(_inUse);
 
index 4bfc178..843882a 100644 (file)
@@ -311,7 +311,7 @@ namespace System.Net.Http
 
             // 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)>
index 8911933..11ac180 100644 (file)
@@ -29,10 +29,10 @@ namespace System.Net.Http
 
             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)
index 537ee6f..3c53400 100644 (file)
@@ -36,7 +36,7 @@ namespace System.Net.Http
 
             public sealed override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) => throw new NotSupportedException();
 
-            public abstract Task FinishAsync();
+            public abstract ValueTask FinishAsync();
         }
     }
 }
index 0c954c4..4d2cba1 100644 (file)
@@ -20,7 +20,7 @@ namespace System.Net.Http
             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))
index 9403b2d..be9300a 100644 (file)
@@ -1177,7 +1177,7 @@ namespace System.Net.Security
             }
         }
 
-        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
@@ -1185,7 +1185,6 @@ namespace System.Net.Security
                 int chunkBytes = Math.Min(buffer.Length, MaxDataSize);
                 await WriteSingleChunk(writeAdapter, buffer.Slice(0, chunkBytes)).ConfigureAwait(false);
                 buffer = buffer.Slice(chunkBytes);
-
             } while (buffer.Length != 0);
         }
 
@@ -1197,7 +1196,7 @@ namespace System.Net.Security
             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);
@@ -1222,16 +1221,16 @@ namespace System.Net.Security
             }
             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
                 {
@@ -1464,7 +1463,7 @@ namespace System.Net.Security
             }
         }
 
-        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();
@@ -1484,7 +1483,7 @@ namespace System.Net.Security
             {
                 ValueTask t = buffer.Length < MaxDataSize ?
                     WriteSingleChunk(writeAdapter, buffer) :
-                    new ValueTask(WriteAsyncChunked(writeAdapter, buffer));
+                    WriteAsyncChunked(writeAdapter, buffer);
                 await t.ConfigureAwait(false);
             }
             catch (Exception e)
index f9d2dc1..75d4c0f 100644 (file)
@@ -765,7 +765,7 @@ namespace System.Net.Security
             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)
@@ -803,7 +803,7 @@ namespace System.Net.Security
         {
             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)
index 7fb43f7..dbeaead 100644 (file)
@@ -37,7 +37,7 @@ namespace System.Net.Security
         {
         }
 
-        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;
index 88da035..0dc6f28 100644 (file)
@@ -55,11 +55,11 @@ namespace System.Net.WebSockets
         }
 
         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,
index 5c497ad..2702709 100644 (file)
@@ -431,7 +431,7 @@ namespace System.IO
             _stream.Flush();
         }
 
-        private async Task FlushWriteAsync(CancellationToken cancellationToken)
+        private async ValueTask FlushWriteAsync(CancellationToken cancellationToken)
         {
             Debug.Assert(_stream != null);
             Debug.Assert(_readPos == 0 && _readLen == 0,
@@ -1117,7 +1117,7 @@ namespace System.IO
             }
 
             // 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
@@ -1125,7 +1125,7 @@ namespace System.IO
         /// 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);
index 00ee3db..65d084b 100644 (file)
@@ -101,9 +101,9 @@ namespace System.Security.Cryptography
         // 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);
@@ -496,7 +496,7 @@ namespace System.Security.Cryptography
         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)
@@ -511,7 +511,7 @@ namespace System.Security.Cryptography
                 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,
index a13dfb2..42623af 100644 (file)
@@ -44,7 +44,7 @@ namespace System.Threading.Channels
                 return
                     cancellationToken.IsCancellationRequested ? new ValueTask(Task.FromCanceled<T>(cancellationToken)) :
                     TryWrite(item) ? default :
-                    new ValueTask(WriteAsyncCore(item, cancellationToken));
+                    WriteAsyncCore(item, cancellationToken);
             }
             catch (Exception e)
             {
@@ -52,7 +52,7 @@ namespace System.Threading.Channels
             }
         }
 
-        private async Task WriteAsyncCore(T innerItem, CancellationToken ct)
+        private async ValueTask WriteAsyncCore(T innerItem, CancellationToken ct)
         {
             while (await WaitToWriteAsync(ct).ConfigureAwait(false))
             {