Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the "await using" syntax correct?

I have the following synchronous code, which works fine:

    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);
        }
    }

I want to change it to be asynchronous. So:

    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);
    }

Which compiles. But one of the analyzers I use (Meziantou.Analyzer) now suggests that I "prefer using 'await using'". I've never used await using (though I've tried several times in the past and have always run into the same problems I'm running into now). But I would like to use it, so:

        await using StreamWriter writer = new StreamWriter(OutputDirectory + @"\export.txt").ConfigureAwait(false);

Now it no longer compiles: CS0029 Cannot implicitly convert type 'System.Runtime.CompilerServices.ConfiguredAsyncDisposable' to 'System.IO.StreamWriter'. OK, fine, so I change it to use var instead:

        await using var writer = new StreamWriter(OutputDirectory + @"\export.txt").ConfigureAwait(false);

Which gets it past the CS0029, but now the later code doesn't compile: Error CS1061 'ConfiguredAsyncDisposable' does not contain a definition for 'WriteLineAsync' (and a similar one for FlushAsync. Soooo... maybe cast it?

            await ((StreamWriter)writer).WriteLineAsync(title).ConfigureAwait(false);

Nope: Error CS0030 Cannot convert type 'System.Runtime.CompilerServices.ConfiguredAsyncDisposable' to 'System.IO.StreamWriter'

I've googled a bunch and read a bunch, both now and several times in the past, but I just have been completely unable to figure out how to use this "await using" thing. How can I do so? Thanks.

like image 963
Bob Vesterman Avatar asked Feb 20 '26 18:02

Bob Vesterman


1 Answers

The await using syntax currently (C# 10) leaves a lot to be desired, regarding its support for configuring the awaiting of IAsyncDisposables. The best we can do is this:

private async Task GenerateExportOutputAsync()
{
    StreamWriter writer = new(Coordinator.OutputDirectory + @"\export.txt");
    await using (writer.ConfigureAwait(false))
    {
        //...
    }
}

...which doesn't prevent us from using the writer variable outside of the await using section by mistake, and it's not really much more compact than not using the await using syntax at all:

private async Task GenerateExportOutputAsync()
{
    StreamWriter writer = new(Coordinator.OutputDirectory + @"\export.txt");
    try
    {
        //...
    }
    finally { await writer.DisposeAsync().ConfigureAwait(false); }
}

Related GitHub issue: Using ConfigureAwait in "await using" declaration.

like image 158
Theodor Zoulias Avatar answered Feb 23 '26 07:02

Theodor Zoulias



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!