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.
using var writer = new StreamWriter("...");
then on the next line:await writer.WriteLineAsync().ConfigureAwait(false);
– OutflowConfigureAwait(false)
only really needs to be used if you're developing a third-party library. If this project is a web or desktop application, you don't need it. Some people recommend you always use it, but that causes more trouble than any good (if any). I never use it. – TacticianIAsyncDisposable.Dispose
on the stream object. It'll useIDisposable.Dispose
instead. – Otilaawait using var writer = new StreamWriter("...") ;
– OutflowConfigureAwait(false)
on that directly, which is the crux of this question. The pages I linked showawait using (_variable_.ConfigureAwait(false))
after assigning something to_variable_
. The variable has the right type, whileawait using
separately captures the configured awaitable used for async disposal. – Otila