-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Closed
Description
Description
Infinite wait. OperationCanceledException was not throwed as expected if only part of required length has been readen from stream.
In example actually has 12 bytes for read, but syntetical code ReadAtLeastAsync wait for 30 bytes. So it leads to infinite wait ignoring cancelation token.
Reproduction Steps
using System.IO.Pipelines;
var cts = new CancellationTokenSource(3000);
var pipe = new Pipe(PipeOptions.Default);
var bytes = new byte[12];
await pipe.Writer.WriteAsync(bytes).ConfigureAwait(false);
var result = await pipe.Reader.ReadAtLeastAsync(30, cts.Token).ConfigureAwait(false);
pipe.Reader.AdvanceTo(result.Buffer.GetPosition(30));
Console.WriteLine("Stage 1");
Expected behavior
Expected getting: System.OperationCanceledException: The operation was canceled.
Actual behavior
Infinitie wait.....
Known Workarounds
Using this code from Microsoft sources avoid infinite wait:
protected static async ValueTask<ReadResult> ReadAtLeastAsyncCore(PipeReader reader, int minimumSize, CancellationToken cancellationToken)
{
while (true)
{
var result = await reader.ReadAsync(cancellationToken).ConfigureAwait(false);
var buffer = result.Buffer;
if (buffer.Length >= minimumSize || result.IsCompleted || result.IsCanceled)
{
return result;
}
// Keep buffering until we get more data
reader.AdvanceTo(buffer.Start, buffer.End);
}
}
Configuration
.net 6.0
System.IO.Pipelines v6.0.2