Как мне получить правильный синтаксис «ожидание использования»?
У меня есть следующий синхронный код, который отлично работает:
private void GenerateExportOutput()
{
using StreamWriter writer = new(Coordinator.OutputDirectory + @"\export.txt");
if (this.WikiPagesToExport.IsEmpty)
{
return;
}
var wanted = new SortedDictionary<string, WikiPage>(this.WikiPagesToExport, StringComparer.Ordinal);
foreach (var title in wanted.Keys)
{
writer.WriteLine(title);
}
}
Я хочу изменить его на асинхронный. Так:
private async Task GenerateExportOutputAsync()
{
using StreamWriter writer = new(Coordinator.OutputDirectory + @"\export.txt");
if (this.WikiPagesToExport.IsEmpty)
{
return;
}
var wanted = new SortedDictionary<string, WikiPage>(this.WikiPagesToExport, StringComparer.Ordinal);
foreach (var title in wanted.Keys)
{
await writer.WriteLineAsync(title).ConfigureAwait(false);
}
await writer.FlushAsync().ConfigureAwait(false);
}
Который компилируется. Но один из анализаторов, которые я использую (Meziantou.Analyzer), теперь предполагает, что я «предпочитаю использовать «ожидание использования»». Я никогда не использовал await using (хотя в прошлом я пытался несколько раз и всегда сталкивался с теми же проблемами, с которыми сталкиваюсь сейчас). Но я хотел бы использовать его, поэтому:
await using StreamWriter writer = new StreamWriter(OutputDirectory + @"\export.txt").ConfigureAwait(false);
Теперь он больше не компилируется:
CS0029 Cannot implicitly convert type 'System.Runtime.CompilerServices.ConfiguredAsyncDisposable' to 'System.IO.StreamWriter'
. Хорошо, хорошо, поэтому я меняю его на использование
var
вместо:
await using var writer = new StreamWriter(OutputDirectory + @"\export.txt").ConfigureAwait(false);
Который проходит мимо CS0029, но теперь более поздний код не компилируется:
Error CS1061 'ConfiguredAsyncDisposable' does not contain a definition for 'WriteLineAsync'
(и аналогичный для
FlushAsync
. Тааааааааааааааааааааааааааааааааааа...а может бросить?
await ((StreamWriter)writer).WriteLineAsync(title).ConfigureAwait(false);
Неа:
Error CS0030 Cannot convert type 'System.Runtime.CompilerServices.ConfiguredAsyncDisposable' to 'System.IO.StreamWriter'
Я много гуглил и читал кучу, как сейчас, так и несколько раз в прошлом, но я просто не мог понять, как использовать эту вещь «ожидание использования». Как я могу это сделать? Спасибо.
2 ответа
В настоящее время синтаксис (C# 10) оставляет желать лучшего в отношении его поддержки настройки ожидания
IAsyncDisposable
с. Лучшее, что мы можем сделать, это:
private async Task GenerateExportOutputAsync()
{
StreamWriter writer = new(Coordinator.OutputDirectory + @"\export.txt");
await using (writer.ConfigureAwait(false))
{
//...
}
}
... что на самом деле не намного компактнее, чем не использовать
await using
синтаксис вообще:
private async Task GenerateExportOutputAsync()
{
StreamWriter writer = new(Coordinator.OutputDirectory + @"\export.txt");
try
{
//...
}
finally { await writer.DisposeAsync().ConfigureAwait(false); }
}
Связанная проблема GitHub: использование ConfigureAwait в объявлении «ожидание использования» .
Это можно сделать в две строки:
private async Task GenerateExportOutputAsync()
{
StreamWriter writer = new(Coordinator.OutputDirectory + @"\export.txt");
await using var _ = writer.ConfigureAwait(false);
//...
}