user56567675
user56567675

Reputation: 159

How should i use async await between my business/service/application layer

Right now my methods look something like this.

ProductManager class in business

public static async Task<List<ProductItem>> GetAllProducts()
{
    var context = GetMyContext();
    return await context.Products.select(x => 
    new ProductItem{ //create item})
    .ToListAsync();
}

ProductService class in service.

public async Task<List<ProductItem>> GetAllProducts()
{
  return await ProductManager.GetAllProducts();
}

ProductController in application.

public async Task<ActionResult> Index()
{
  var ps = new ProductService();
  var productsAsync = ps.GetAllProducts();
  // Do other work.
  var products = await productsAsync;
  return View(products);
}

This application gets high usage, Is this way of doing it totally wrong ? Should I be await every method ? Will this start a new thread every time await is called ?

Upvotes: 1

Views: 1066

Answers (2)

Stephen Cleary
Stephen Cleary

Reputation: 456887

This application gets high usage, Is this way of doing it totally wrong?

No; it looks good to me.

Should I be await every method?

Yes. Once you put in the first await (in ProductManager), then its callers should be awaited, and their callers awaited, and so on, up to the controller action method. This "growth" of async is entirely natural; it's called "async all the way" in my MSDN article on async best practices.

Will this start a new thread every time await is called?

No. Await is about freeing up threads, not using more threads. I have an async intro on my blog that describes how async and await work.

Upvotes: 4

Panagiotis Kanavos
Panagiotis Kanavos

Reputation: 131581

await simply awaits for something to complete. If you don't need the results of a task in your method, you don't need to await it. GetAllProducts should simply return the results of ToListAsync.

public static Task<List<ProductItem>> GetAllProducts()
{
    var context = GetMyContext();
    return context.Products
                  .Select(x => new ProductItem{ //create item})
                  .ToListAsync();
}

async/await adds a bit of overhead, since the compiler has to generate a state machine that stores the original synchronization context, waits for the awaited task to finish and then restores the original synchronization context.

Adding async/await on a method that doesn't need to process the result of the task simply adds overhead. In fact, there are some Roslyn analyzers that detect and fix this issue

Upvotes: 1

Related Questions