tabs ↹ over ␣ ␣ ␣ spaces

by Jiří {x2} Činčura

Task<IDisposable> surprise

15 Dec 2022 1 mins .NET, C#

This combination of Task and IDisposable surprised me quite well. And yes, it’s my fault. As usual.

I was writing a simple asynchronous method that returns an object that implements IDisposable. Really barebones example.

async Task<IDisposable> Foo()
{
    return default;
}

And then I used this method like this. Nothing to talk about. Or?

using (Foo())
{
}

Can you see the problem? No? Neither did I. With this call, I’m disposing the task (Task also implements IDisposable) that I just started/received, not the disposable itself.

The correct code is like this.

using (await Foo())
{
}

Which I’ve found after I deployed an application to my Raspberry Pi and it failed. I suppose that qualifies me for “testing in production guy” label. 😎

And now, forever, I’ll remember it and I’ll be carefull around this combination. And maybe you’ll too.

Profile Picture Jiří Činčura is .NET, C# and Firebird expert. He focuses on data and business layers, language constructs, parallelism, databases and performance. For almost two decades he contributes to open-source, i.e. FirebirdClient. He works as a senior software engineer for Microsoft. Frequent speaker and blogger at www.tabsoverspaces.com.