Today I was reading about async/await best practices and run across this:
https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md#async-void
Previously, for my fire-and-forget async methods, I was just calling the method and ignoring the returned Task
:
DoSomethingAsync();
The compiler would produce a warning about the async method not being awaited, so I ended up adding a workaround to prevent it. There are several ways suggested here in StackOverflow, for instance by using a Task.Forget()
extension method or a discard.
The article above, instead, suggests:
Task.Run(DoSomethingAsync);
I had never seen the Task.Run()
overload that takes a Func<Task>
argument. I looked up the documentation and found it confusing.
Assuming an async method is passed in (ie. defined as async Task DoSomethingAsync()
), does that mean 2 tasks are created, one to run the async method and a proxy one that wraps the first? Or just 1 task?
In general, what's the use case for this overload? If a method already returns a Task
, why not just await that?
EDIT: I don't feel like this is a duplicate of When correctly use Task.Run and when just async-await, but it looks very similar to await task.run vs await c#, which focuses on the Task.Run(Func<Task)
overload. It doesn't explain in deep detail what happens in terms of tasks created and execution context differences though.