Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restore: fix performance regression on .NET Core 2.1+ #2430

Merged
merged 1 commit into from
Oct 8, 2018

Conversation

dtivel
Copy link
Contributor

@dtivel dtivel commented Sep 20, 2018

Resolve NuGet/Home#7314.

The core problem with the original code is that it forces a buffer to be flushed synchronously rather than asynchronously (and, actually worse than that, as a sync-over-async operation, meaning it’s performing an asynchronous operation and then blocking waiting for it to complete). That would occur as part of the Seek, or if the validation wasn’t there, as part of Dispose’ing the FileStream, both synchronous operations.

The right fix would be to add an “await FileStream.FlushAsync();” before doing the seeking/validation/closing. That flush would ensure that the buffer is empty when Seek/Dispose/etc. are closed, so there’s nothing more to flush. However, there’s a bug in FlushAsync that’s causing it to also do the key part of the flush synchronously as well.

So, the workaround is to avoid buffering, such that nothing needs to be flushed as part of Seek/Dispose. That’s what bufferSize=1 does.

However, the concern expressed was that disabling that buffering would avoid this problem for the writing but would slow down the reading/validation. So, the fix splits it into two streams: one used for writing with buffering disabled, and then one used for reading that has buffering enabled still.

CC @rrelyea

FileShare.None,
BufferSize,
useAsync: true))
{
Copy link
Contributor

Choose a reason for hiding this comment

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

Will it add any performance impact for desktop frameworks since it will always open separate streams to read and write?

Or shouldn't we just restrict these separate streams for netcore?

Copy link
Contributor

@jainaashish jainaashish Oct 8, 2018

Choose a reason for hiding this comment

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

Discussed offline and got this resolved. Updated the PR description accordingly

@jainaashish jainaashish merged commit e0340cc into dev Oct 8, 2018
jainaashish pushed a commit that referenced this pull request Oct 8, 2018
@nkolev92 nkolev92 deleted the dev-dtivel-filestream branch October 8, 2018 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Restore: performance regression using new .NET Core 2.1 HTTP stack
3 participants