Skip to content

[Analyzer Proposal]: Warn on use of StreamReader.EndOfStream in async methodsΒ #98834

@stephentoub

Description

@stephentoub

StreamReader.EndOfStream is a pernicious little property.
https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.endofstream?view=net-8.0

It seems harmless, like it's just checking something quick and easy. And if there's already some data buffered in the StreamReader, it is: if there's remaining data to read, it's not at the end of the stream. But if there's no data buffered, the only way it can know if it's at the end of the stream is to try to read from the stream and wait until either at least a byte of data is available or it gets back eof. That is a synchronous blocking operation.

In the last month, I've seen several uses of EndOfStream along the lines of:

while (!reader.EndOfStream)
{
    string? line = await reader.ReadLineAsync();
    ...
}

This is problematic because while the developer obviously intended to do their I/O asynchronously, there's a really good chance most of it will end up being done synchronously as part of EndOfStream, making the API synchronously instead of asynchronously blocking. Separately, even if this were intended to be entirely synchronous, this doesn't actually need to use EndOfStream: ReadLine{Async} will give back null if at EOF, so that can be used instead of EndOfStream.

While there's rarely a good reason to use EndOfStream, I'm not sure it rises to the level of obsoleting it. But we should have an analyzer that warns on any use of it in an async method, as it's almost always going to be doing the wrong thing there.

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-approvedAPI was approved in API review, it can be implementedarea-System.IOcode-analyzerMarks an issue that suggests a Roslyn analyzer

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions