Как мне получить правильный синтаксис «ожидание использования»?

У меня есть следующий синхронный код, который отлично работает:

          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);
    //...
}
Другие вопросы по тегам