-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
EDIT: link to updated proposal: #20824 (comment)
Today we have the following methods on StreamReader:
public class StreamReader
{
public Task<string> ReadLineAsync();
public Task<string> ReadToEndAsync();
public Task<int> ReadAsync(char[] buffer, int index, int count);
public Task<int> ReadBlockAsync(char[] buffer, int index, int count);
}None of these support cancellation via CancellationTokens, even though the underlying Stream ReadAsync API's do
Proposed API
Add the following methods
public class StreamReader
{
public Task<string> ReadLineAsync(CancellationToken token);
public Task<string> ReadToEndAsync(CancellationToken token);
public Task<int> ReadAsync(char[] buffer, int index, int count, CancellationToken token);
public Task<int> ReadBlockAsync(char[] buffer, int index, int count, CancellationToken token);
}Motivation
Since these methods read from an underlying stream that may have long delays before data is available, they can block for long periods of time. Especially if the underlying stream is network based.
When trying to create a responsive application in these circumstances, where long running operations that might never return can be cancelled to return control back to the user, the inability to cancel these operations in difficult.
Currently the only real option is to fork the call into a fake cancellable operation that ends up ignoring original Task when a cancellation happens, with something like ThreadingTools.WithCancellation. But that leaves the reading Task (and potentially the stream and any continuations registered on it) floating, unreferenced.