-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Enable async-over-sync FileStream read/writes to be cancelable on Windows #87103
Conversation
67e74a5
to
4df0da7
Compare
Tagging subscribers to this area: @dotnet/area-system-io Issue DetailsUsing the same helpers we previously used to enable this in pipe streams on Windows, enable FileStream.Read/WriteAsync on a FileStream created for synchronous I/O to be cancelable. This also makes some tweaks to those helpers to reduce allocation when a cancelable token is supplied. Fixes #84290 This also makes some tweaks to those helpers to reduce allocation when a cancelable token is supplied. There's no meaningful improvement for FileStream, since it was effectively ignoring the CancellationToken previously. So here's a benchmark showing the impact on PipeStream, which as noted was already cancelable using this mechanism:
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.IO.Pipes;
using System.Threading.Tasks;
using System.Threading;
[MemoryDiagnoser(false)]
public class Program
{
static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private readonly byte[] _buffer = new byte[1];
private AnonymousPipeServerStream _server;
private AnonymousPipeClientStream _client;
[GlobalSetup]
public void Setup()
{
_server = new AnonymousPipeServerStream(PipeDirection.Out);
_client = new AnonymousPipeClientStream(PipeDirection.In, _server.ClientSafePipeHandle);
}
[GlobalCleanup]
public void Cleanup()
{
_server.Dispose();
_client.Dispose();
}
[Benchmark(OperationsPerInvoke = 1000)]
public async Task ReadWriteAsync()
{
for (int i = 0; i < 1000; i++)
{
ValueTask<int> read = _client.ReadAsync(_buffer, _cts.Token);
await _server.WriteAsync(_buffer, _cts.Token);
await read;
}
}
}
|
…dows Using the same helpers we previously used to enable this in pipe streams on Windows, enable FileStream.Read/WriteAsync on a FileStream created for synchronous I/O to be cancelable. This also makes some tweaks to those helpers to reduce allocation when a cancelable token is supplied.
4df0da7
to
d7bd8d5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, it's great that the helper components were so easy to re-use. Thanks @stephentoub !
src/libraries/Common/src/System/Threading/AsyncOverSyncWithIoCancellation.cs
Outdated
Show resolved
Hide resolved
src/libraries/Common/src/System/Threading/AsyncOverSyncWithIoCancellation.cs
Show resolved
Hide resolved
src/libraries/Common/src/System/Threading/AsyncOverSyncWithIoCancellation.cs
Show resolved
Hide resolved
…ancellation.cs Co-authored-by: Adam Sitnik <adam.sitnik@gmail.com>
Using the same helpers we previously used to enable this in pipe streams on Windows, enable FileStream.Read/WriteAsync on a FileStream created for synchronous I/O to be cancelable. This also makes some tweaks to those helpers to reduce allocation when a cancelable token is supplied.
Fixes #84290
This also makes some tweaks to those helpers to reduce allocation when a cancelable token is supplied. There's no meaningful improvement for FileStream, since it was effectively ignoring the CancellationToken previously. So here's a benchmark showing the impact on PipeStream, which as noted was already cancelable using this mechanism: