提交 a123fb2c 编写于 作者: S Stephen Toub 提交者: GitHub

Fix FileStream.FlushAsync() to behave like Flush() (dotnet/coreclr#24902)

Flush() behaves like Flush(false) and writes out any buffered data but doesn't P/Invoke to FlushFileBuffers/FSync to flush the OS buffers.

But whereas FlushAsync() is supposed to just be an async equivalent of Flush(), it's actually behaving like Flush(true).  This makes FlushAsync() inconsistent and much more expensive.  (This is separate from FlushAsync not actually being async, which is an impactful problem to be solved separately.)

This changes FlushAsync to behave like Flush()/Flush(false) rather than Flush(true).  If someone wants the FlushFileBuffers/FSync behavior, they can call Flush(true).

Commit migrated from https://github.com/dotnet/coreclr/commit/436debb93c390e144f9c25b5d1922ac7780745f4
上级 9c2608cb
......@@ -1555,10 +1555,6 @@ public void UnsafeOnCompleted(Action continuation)
}
}
// Unlike Flush(), FlushAsync() always flushes to disk. This is intentional.
// Legend is that we chose not to flush the OS file buffers in Flush() in fear of
// perf problems with frequent, long running FlushFileBuffers() calls. But we don't
// have that problem with FlushAsync() because we will call FlushFileBuffers() in the background.
private Task FlushAsyncInternal(CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
......@@ -1567,7 +1563,7 @@ private Task FlushAsyncInternal(CancellationToken cancellationToken)
if (_fileHandle.IsClosed)
throw Error.GetFileNotOpen();
// TODO: https://github.com/dotnet/corefx/issues/32837 (stop doing this synchronous work).
// TODO: https://github.com/dotnet/corefx/issues/32837 (stop doing this synchronous work!!).
// The always synchronous data transfer between the OS and the internal buffer is intentional
// because this is needed to allow concurrent async IO requests. Concurrent data transfer
// between the OS and the internal buffer will result in race conditions. Since FlushWrite and
......@@ -1584,20 +1580,8 @@ private Task FlushAsyncInternal(CancellationToken cancellationToken)
return Task.FromException(e);
}
if (CanWrite)
{
return Task.Factory.StartNew(
state => ((FileStream)state!).FlushOSBuffer(),
this,
cancellationToken,
TaskCreationOptions.DenyChildAttach,
TaskScheduler.Default);
}
else
{
return Task.CompletedTask;
}
}
private void LockInternal(long position, long length)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册