Skip to content

Added IAsyncDisposable to TextReader#89477

Closed
dersia wants to merge 4 commits intodotnet:mainfrom
dersia:main
Closed

Added IAsyncDisposable to TextReader#89477
dersia wants to merge 4 commits intodotnet:mainfrom
dersia:main

Conversation

@dersia
Copy link

@dersia dersia commented Jul 25, 2023

  • added IAsyncDisposable to TextReader.
  • Implemnted IAsyncDisposable for StreamReader as it is implemented for StreamWriter.
  • Changed StreamWriter to call base.Dispose(disposing) and set _disposed to true, even if stream is not closable

fixes #88244 #88246

I still think there are some bugs in StreamWriter and I think it makes sense to add CloseAsync() to Stream, since as of now, it is still always calling Dispose(true) which is sync, but I will open another issue for that.

… StreamReader as it is implemented for StreamWriter. Changed StreamWriter to call base.Dispose(disposing) and set _disposed to true, even if stream is not closable
@ghost ghost added area-System.IO community-contribution Indicates that the PR has been added by a community member labels Jul 25, 2023
@ghost
Copy link

ghost commented Jul 25, 2023

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

Issue Details
  • added IAsyncDisposable to TextReader.
  • Implemnted IAsyncDisposable for StreamReader as it is implemented for StreamWriter.
  • Changed StreamWriter to call base.Dispose(disposing) and set _disposed to true, even if stream is not closable

fixes #88244

I still think there are some bugs in StreamWriter and I think it makes sense to add CloseAsync() to Stream, since as of now, it is still always calling Dispose(true) which is sync, but I will open another issue for that.

Author: dersia
Assignees: -
Labels:

area-System.IO

Milestone: -

@dersia
Copy link
Author

dersia commented Jul 25, 2023

I might need some help to understand where the issue from the Analysis is coming from. Did I miss something?

@danmoseley
Copy link
Member

The validation errors are unrelated.

Copy link
Member

@jozkee jozkee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ghost ghost added the needs-author-action An issue or pull request that requires more info or actions from the author. label Jul 26, 2023
@jozkee
Copy link
Member

jozkee commented Jul 26, 2023

CI issues are related, you need to add the API changes to the ref assembly.

@Neme12
Copy link

Neme12 commented Jul 26, 2023

I still think there are some bugs in StreamWriter and I think it makes sense to add CloseAsync() to Stream, since as of now, it is still always calling Dispose(true) which is sync, but I will open another issue for that.

There's no reason to add CloseAsync. There's already DisposeAsync - that's what it should call.

@ghost ghost removed the needs-author-action An issue or pull request that requires more info or actions from the author. label Jul 26, 2023
@dersia
Copy link
Author

dersia commented Jul 26, 2023

Can you please also add tests for StreamReader? You can get inspiration from https://github.com/dotnet/runtime/blob/main/src/libraries/System.IO/tests/StreamWriter/StreamWriter.DisposeAsync.cs

I wrote a test already, but I couldnt figure out how to update the ref assemblies and so I couldn't run the test, but now I know how to do it

Added StreamWriter.CloseStreamFromDisposeAsync
Added same for StreamReader
Added missing Refs
Added Tests
@dersia
Copy link
Author

dersia commented Jul 28, 2023

all comments are addressed i think. should I resolve the conversations or is who started the conversions going to resolve it? I usually wait for the person that started it to resolve it, so I know they are OK with the change.

@danmoseley
Copy link
Member

It's up to you but typically folks resolve comments when they push the change that addresses them.

@dersia dersia requested a review from jozkee July 28, 2023 16:32
Assert.Null(await input.ReadLineAsync(default));
Assert.Equal("", await input.ReadToEndAsync());
Assert.Equal("", await input.ReadToEndAsync(default));
await input.DisposeAsync();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add this line to the existing test above and remove this one test to avoid duplication?

Copy link
Author

@dersia dersia Jul 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these to methods are testing different behavior, since Dispose is calling "Close()" on the underlying stream and DisposeAsync() is calling "DisposeAsync()" on the underlying stream. But if this isn't a concern I will happily change this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jozkee what do you think we should do here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think you should apply my suggestion here because TestNullTextReaderAsync above is already testing Async conterparts.

Assert.Equal(token, ex.CancellationToken);
ex = await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await input.ReadToEndAsync(token));
Assert.Equal(token, ex.CancellationToken);
await input.DisposeAsync();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

{
_disposed = true;
_charLen = 0;
await base.DisposeAsync().ConfigureAwait(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I stared at this for a long time and seems to me that this is the right thing to do, as per the docs:

An object must also call the DisposeAsync method of its base class if the base class implements IAsyncDisposable.

I don't know why we weren't doing this before. @stephentoub thoughts?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jozkee, @stephentoub what do you think we should do here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you have here looks good to me.

@jozkee
Copy link
Member

jozkee commented Aug 7, 2023

@dersia ping, I don't see your commits addressing the feedback. Bear in mind the code cut for .NET 8 RC1 is next week.

@jeffhandley
Copy link
Member

I've reviewed this PR to assess whether or not we'd want to merge it in for .NET 8, and my conclusion is that we should hold off on this until .NET 9 Preview 1. If there is a compelling value proposition for this to make it into .NET 8 though, I'm happy to take more data points into consideration.

My considerations thus far are:

  • This involves dispose for a core type
  • Analyzer diagnostic CA2215 will be raised on derived types that implement IAsyncDisposable
  • Compiler diagnostic CS0108 will be raised on derived types that implement IAsyncDisposable
  • Introducing potential diagnostics for derived classes at this stage in the release has high likelihood of breaking code flow and requiring churn upstack

With the potential for the diagnostics to be introduced, getting this into .NET 9 Preview 1 will still require we scope out upstack derivatives and assess if this will disrupt code flow. If this does introduce the need to make compensating changes in other repos, then we would consider handling this as a source-incompatible breaking change. We need to assess the upstack code flow impact before merging; if compensating changes are required, then we'll want to hold off on merge until .NET 8 is locked down for GA so that we don't disrupt code flow or introduce merge conflicts.

@dersia Thank you for this contribution and the efforts you've put into it. With the plan of waiting for .NET 9 Preview 1, we would be letting this PR remain open for several weeks before merging it in.

@jeffhandley jeffhandley added this to the 9.0.0 milestone Aug 10, 2023
@jozkee jozkee added the needs-author-action An issue or pull request that requires more info or actions from the author. label Aug 11, 2023
@ghost ghost added the no-recent-activity label Aug 25, 2023
@ghost
Copy link

ghost commented Aug 25, 2023

This pull request has been automatically marked no-recent-activity because it has not had any activity for 14 days. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will remove no-recent-activity.

@ghost
Copy link

ghost commented Sep 9, 2023

This pull request will now be closed since it had been marked no-recent-activity but received no further activity in the past 14 days. It is still possible to reopen or comment on the pull request, but please note that it will be locked if it remains inactive for another 30 days.

@ghost ghost closed this Sep 9, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Oct 9, 2023
This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.IO community-contribution Indicates that the PR has been added by a community member needs-author-action An issue or pull request that requires more info or actions from the author. no-recent-activity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[API Proposal]: Implement IAsyncDisposable on TextReader

5 participants