I'm writing a method which asynchronously writes separate lines of text to a file. If it's cancelled it deletes the created file and jumps out of the loop.
This is the simplified code which works fine... And I marked 2 points which I'm not sure how they are being handled. I want the code to not block the thread in any case.
public async Task<IErrorResult> WriteToFileAsync(string filePath,
CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
using var stream = new FileStream(filePath, FileMode.Create);
using var writer = new StreamWriter(stream, Encoding.UTF8);
foreach (var line in Lines)
{
if (cancellationToken.IsCancellationRequested)
{
//
// [1] close, delete and throw if cancelled
//
writer.Close();
stream.Close();
if (File.Exists(filePath))
File.Delete(filePath);
throw new OperationCanceledException();
}
// write to the stream
await writer.WriteLineAsync(line.ToString());
}
//
// [2] flush and let them dispose
//
await writer.FlushAsync();
await stream.FlushAsync();
// await stream.DisposeAsync(); ??????
return null;
}
1
I'm calling Close()
on FileStream
and StreamWriter
and I think it will run synchronously and blocks the thread. How can I improve this? I don't want to wait for it to flush the buffer into the file and then delete the file.
2
I suppose the Dispose
method will be called and not DisposeAsync
at the end of the using
scope. (is this assumption correct?).
So Dispose
blocks the thread and in order to prevent that I'm flushing first with FlushAsync
so that Dispose
would perform less things. (to what extent is this true?)
I could also remove using
and instead I could write DisposeAsync
manually in these two places. But it will decrease readability.
If I open the FileStream
with useAsync = true
would it automatically call DisposeAsync
when using
block ends?
Any explanation or a variation of the above code which performs better is appreciated.
Stream
class was implementingIAsyncDisposable
you could ensure thatDisposeAsync
would be finally called byawait using
the stream. But it doesn't implement this interface... – Uglyawait using
:) – CzarismStream
class doesn't implement theIAsyncDisposable
based on the documentation. I should look at the Object Explorer. Unfortunately the online documentation is not updated with the new C# 8 features yet. – UglyStream
implementsIAsyncDisposable
andawait using
pretty much works. maybe the documentation is outdated – Czarism