Как вы понимаете, оператор using
будет вызывать Dispose()
, а не DisposeAsync()
.
C # 8 принес новый синтаксис await using
, но по какой-то причине он не упоминается в Что нового в C # 8.0 article.
Но это , упомянутое в другом месте .
await using var stream = new FileStream(filePath, FileMode.Create);
await using var writer = new StreamWriter(stream, Encoding.UTF8);
Но также обратите внимание, что это будет работать, только если:
- Вы используете .NET Core 3.0+, так как именно тогда
IAsyncDisposable
был представлен, или - Установите Microsoft.Bcl.AsyncInterfaces NuGet пакет. Хотя это только добавляет интерфейсы и не включает версии
Stream
типов (FileStream
, StreamWriter
и т. Д.), Которые его используют.
Даже в Объявляя статью .NET Core 3.0 , IAsyncDisposable
упоминается только мимоходом и никогда не раскрывается.
С другой стороны, вам не нужно делать это (я вижупочему сейчас):
writer.Close();
stream.Close();
Поскольку документация для Close
гласит:
Этот метод вызывает Dispose, указывая true
для освобождения всех ресурсов,Вам не нужно специально вызывать метод Close. Вместо этого убедитесь, что каждый объект Stream правильно расположен.
Поскольку вы используете using
, Dispose()
(или DisposeAsync()
) будет вызываться автоматически, а Close
не будетвсе, что еще не происходит.
Так что, если вам нужно конкретно закрыть файл, но вы хотите сделать это асинхронно, просто вызовите DisposeAsync()
вместо этого. Он делает то же самое.
await writer.DisposeAsync();
public async Task<IErrorResult> WriteToFileAsync(string filePath,
CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
await using var stream = new FileStream(filePath, FileMode.Create);
await using var writer = new StreamWriter(stream, Encoding.UTF8);
foreach (var line in Lines)
{
if (cancellationToken.IsCancellationRequested)
{
// not possible to discard, FlushAsync is covered in DisposeAsync
await writer.DisposeAsync(); // use DisposeAsync instead of Close to not block
if (File.Exists(filePath))
File.Delete(filePath);
throw new OperationCanceledException();
}
// write to the stream
await writer.WriteLineAsync(line.ToString());
}
// FlushAsync is covered in DisposeAsync
return null;
}