public async Task SendLargePayloadOnManyChannels()
    {
        if (await this.ExecuteInIsolationAsync())
        {
            byte[][] serverBuffers = Enumerable.Range(1, ChannelCount).Select(i => new byte[SegmentSize]).ToArray();

            (MultiplexingStream mxServer, MultiplexingStream mxClient) = await Task.WhenAll(
                MultiplexingStream.CreateAsync(this.serverPipe, this.TimeoutToken).WithCancellation(this.TimeoutToken),
                MultiplexingStream.CreateAsync(this.clientPipe, this.TimeoutToken).WithCancellation(this.TimeoutToken));

            await this.WaitForQuietPeriodAsync();

            // Warm up
            await RunAsync(ChannelCount * 2);

            long memory1 = GC.GetTotalMemory(true);
            var  sw      = Stopwatch.StartNew();
            await RunAsync(SegmentCount);

            sw.Stop();
            long memory2   = GC.GetTotalMemory(false);
            long allocated = memory2 - memory1;
            this.Logger.WriteLine("{0} bytes allocated ({1} per segment)", allocated, allocated / SegmentCount);
            this.Logger.WriteLine("{0} bytes transmitted in each of {1} segments in {2}ms on {3} channel(s)", SegmentSize, SegmentCount, sw.ElapsedMilliseconds, ChannelCount);

            async Task RunAsync(int segmentCount)
            {
                Requires.Argument(segmentCount >= ChannelCount, nameof(segmentCount), "Cannot send {0} segments over {1} channels.", segmentCount, ChannelCount);
                await Task.WhenAll(
                    Task.Run(async delegate
                {
                    await Task.WhenAll(
                        Enumerable.Range(1, ChannelCount).Select(c => Task.Run(async delegate
                    {
                        byte[] serverBuffer = serverBuffers[c - 1];
                        MultiplexingStream.Channel?channel = await mxServer.OfferChannelAsync(string.Empty, this.TimeoutToken).WithCancellation(this.TimeoutToken);
                        for (int i = 0; i < segmentCount / ChannelCount; i++)
                        {
                            await channel.Output.WriteAsync(serverBuffer, this.TimeoutToken);
                        }
                    })));
                }),
                    Task.Run(async delegate
                {
                    await Task.WhenAll(
                        Enumerable.Range(1, ChannelCount).Select(c => Task.Run(async delegate
                    {
                        MultiplexingStream.Channel?channel = await mxClient.AcceptChannelAsync(string.Empty, this.TimeoutToken).WithCancellation(this.TimeoutToken);
                        int expectedTotalBytesRead         = segmentCount / ChannelCount * SegmentSize;
                        int totalBytesRead = 0;
                        do
                        {
                            System.IO.Pipelines.ReadResult readResult = await channel.Input.ReadAsync(this.TimeoutToken);
                            totalBytesRead += (int)readResult.Buffer.Length;
                            channel.Input.AdvanceTo(readResult.Buffer.End);
                            readResult.ScrubAfterAdvanceTo();
                        }while (totalBytesRead < expectedTotalBytesRead);
                        Assert.Equal(expectedTotalBytesRead, totalBytesRead);
                    })));
                })).WithCancellation(this.TimeoutToken);
            }
        }
    }
Esempio n. 2
0
 /// <summary>
 /// Attempt to synchronously read data the <see cref="PipeReader"/>.
 /// </summary>
 /// <param name="result">The <see cref="ReadResult"/></param>
 /// <returns>True if data was available, or if the call was canceled or the writer was completed.</returns>
 /// <remarks>If the pipe returns false, there's no need to call <see cref="AdvanceTo(SequencePosition, SequencePosition)"/>.</remarks>
 public abstract bool TryRead(out ReadResult result);
Esempio n. 3
0
 public override bool TryRead(out ReadResult result)
 {
     return(_pipe.TryRead(out result));
 }
        public override bool TryRead(out ReadResult result)
        {
            ThrowIfCompleted();

            return(TryReadInternal(InternalTokenSource, out result));
        }
 public bool TryRead(out ReadResult result)
 {
     result = default;
     return(false);
 }