protected internal override ValueTask <HttpReadType> ReadAsync(int version, CancellationToken cancellationToken) { if (IsDisposed(version, out ValueTask <HttpReadType> task)) { return(task); } return(_request.ReadAsync(cancellationToken)); }
public async Task Pipelining_PausedReads_Success() { if (TrickleForceAsync) { // This test depends on synchronous completion of reads, so will not work when async completion is forced. return; } const int PipelineLength = 10; using var semaphore = new SemaphoreSlim(0); await RunMultiStreamTest( async (client, serverUri) => { ValueHttpRequest prev = (await client.CreateNewRequestAsync(Version, HttpVersionPolicy.RequestVersionExact)).Value; prev.ConfigureRequest(contentLength: 0, hasTrailingHeaders: false); prev.WriteRequest(HttpMethod.Get, serverUri); await prev.CompleteRequestAsync(); await semaphore.WaitAsync(); for (int i = 1; i < PipelineLength; ++i) { ValueHttpRequest next = (await client.CreateNewRequestAsync(Version, HttpVersionPolicy.RequestVersionExact)).Value; next.ConfigureRequest(contentLength: 0, hasTrailingHeaders: false); next.WriteRequest(HttpMethod.Get, serverUri); await next.CompleteRequestAsync(); await semaphore.WaitAsync(); ValueTask <HttpReadType> nextReadTask = next.ReadAsync(); // wait for write to complete to guarantee DisposeAsync() will complete synchronously. Assert.False(nextReadTask.IsCompleted); await prev.DisposeAsync(); Assert.True(nextReadTask.IsCompleted); Assert.Equal(HttpReadType.FinalResponse, await nextReadTask); prev = next; } await prev.DisposeAsync(); }, async server => { for (int i = 0; i < PipelineLength; ++i) { await server.ReceiveAndSendSingleRequestAsync(); semaphore.Release(); } }); }
protected internal override async ValueTask <HttpReadType> ReadAsync(int version, CancellationToken cancellationToken) { ThrowIfDisposed(version); HttpReadType readType = await _request.ReadAsync(cancellationToken).ConfigureAwait(false); ReadType = readType; if (readType == HttpReadType.FinalResponse) { StatusCode = _request.StatusCode; Version = _request.Version; } return(readType); }
static async Task Main(string[] args) { Environment.SetEnvironmentVariable("DOTNET_SYSTEM_THREADING_POOLASYNCVALUETASKS", "1"); await using ConnectionFactory connectionFactory = new MemoryConnectionFactory(); await using ConnectionListener listener = await connectionFactory.ListenAsync(); await using SimpleHttp1Server server = new(listener, triggerBytes, responseBytes); await using Connection connection = await connectionFactory.ConnectAsync(listener.EndPoint !); await using HttpConnection httpConnection = new Http1Connection(connection, HttpPrimitiveVersion.Version11); if (!Debugger.IsAttached) { Console.WriteLine("Press any key to continue, once profiler is attached..."); Console.ReadKey(); } for (int i = 0; i < 1000000; ++i) { await using ValueHttpRequest request = (await httpConnection.CreateNewRequestAsync(HttpPrimitiveVersion.Version11, HttpVersionPolicy.RequestVersionExact)) ?? throw new Exception("HttpConnection failed to return a request"); request.ConfigureRequest(contentLength: 0, hasTrailingHeaders: false); request.WriteRequest(HttpRequest.GetMethod, authority, pathAndQuery); request.WriteHeader(preparedRequestHeaders); foreach ((byte[] name, byte[] value) in dynamicRequestHeaders) { request.WriteHeader(name, value); } await request.CompleteRequestAsync(); while (await request.ReadAsync() != HttpReadType.EndOfStream) { // do nothing, just draining. } } }