andrewthedev
andrewthedev

Reputation: 337

Async await from aspnet controller down call stack

Given the following code snippet of an aspnet controller, is it a requirement to have async/await at the top level, or is it valid to return a Task?

The scenario assumes there is some IO (data access) that uses async in underlying code in the repository.

controller

public class SomeController
{
    private readonly ISomeService service;

    public SomeController(ISomeService service) => _service = service;

    public async Task<SomeResult> GetAsync()
    {
        return await _someService.GetAsync();
    }
}

service

public class SomeService
{
    private readonly ISomeRepo repo;

    public SomeController(ISomeRepo repo) => _repo = repo;

    public async Task<SomeResult> GetAsync()
    {
        return await _repo.FirstOrDefault();
    }
}

Thus in the above, is the async/await required? It compiles fine without. Async Fixer suggests async await is not required either.

This is a great article:

https://saebamini.com/common-async-and-await-misconceptions/#you-need-to-use-asyncawait-in-the-whole-call-stack

But this is contradictory to other bits of information.

When should I use Async Controllers in ASP.NET MVC?

https://learn.microsoft.com/en-us/archive/msdn-magazine/2014/october/async-programming-introduction-to-async-await-on-asp-net

https://exceptionnotfound.net/using-async-and-await-in-asp-net-what-do-these-keywords-mean/

async/await in MVC controller's action

But the question is, what is the correct implementation for async/await in the above aspnet context?

Feel free to list various caveats.

Upvotes: 1

Views: 93

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 456437

First, it's important to note that either way, the code is asynchronous.

That said, I generally recommend people to start with async/await everywhere and then only elide the keywords in trivial cases. There are several caveats when eliding async and await, including exceptions and using statements. So as a general rule, if the implementation is truly trivial (literally just "forward to another method"), then feel free to elide async/await; everywhere else, keep the async/await keywords. They have minimal overhead and guarantee correct semantics for nontrivial methods.

Upvotes: 3

Related Questions