Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Architecture for async/await

If you are using async/await at a lower level in your architecture, is it necessary to "bubble up" the async/await calls all the way up, is it inefficient since you are basically creating a new thread for each layer (asynchronously calling an asynchronous function for each layer, or does it not really matter and is just dependent on your preference?

I'm using EF 6.0-alpha3 so that I can have async methods in EF.

My repository is such:

public class EntityRepository<E> : IRepository<E> where E : class {     public async virtual Task Save()     {         await context.SaveChangesAsync();     } } 

Now my business layer is as such:

public abstract class ApplicationBCBase<E> : IEntityBC<E> {     public async virtual Task Save()     {         await repository.Save();     } } 

And then of course my method in my UI would have the follow the same pattern when calling.

Is this:

  1. necessary
  2. negative on performance
  3. just a matter of preference

Even if this isn't used in separate layers/projects the same questions applies to if I am calling nested methods in the same class:

    private async Task<string> Dosomething1()     {         //other stuff          ...         return await Dosomething2();     }     private async Task<string> Dosomething2()     {         //other stuff          ...         return await Dosomething3();     }     private async Task<string> Dosomething3()     {         //other stuff          ...         return await Task.Run(() => "");     } 
like image 349
valdetero Avatar asked Mar 19 '13 15:03

valdetero


People also ask

How does async await work?

The async keyword turns a method into an async method, which allows you to use the await keyword in its body. When the await keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete. await can only be used inside an async method.

Does async await use thread pool?

Await Keyword Basically, it returns to caller thread with reference to ongoing task and stop execution of code below that line and release the current thread to thread pool to process another request. Async and await are always used together, if not, then there will be something wrong.

How does async await work under the hood?

Async/Await enables us to write asynchronous code in a synchronous fashion, which produces cleaner and easier-to-understand logic. Under the hood, it's just syntactic sugar using generators and yield statements to “pause” execution.

What is async and await in .NET core?

Async and await in C# are the code markers, which marks code positions from where the control should resume after a task completes. Let's start with practical examples for understanding the programming concept.


1 Answers

If you are using async/await at a lower level in your architecture, is it necessary to "bubble up" the async/await calls all the way up, is it inefficient since you are basically creating a new thread for each layer (asynchronously calling an asynchronous function for each layer, or does it not really matter and is just dependent on your preference?

This question suggests a couple of areas of misunderstanding.

Firstly, you don't create a new thread each time you call an asynchronous function.

Secondly, you don't need to declare an async method, just because you're calling an asynchronous function. If you're happy with the task that's already being returned, just return that from a method which doesn't have the async modifier:

public class EntityRepository<E> : IRepository<E> where E : class {     public virtual Task Save()     {         return context.SaveChangesAsync();     } }  public abstract class ApplicationBCBase<E> : IEntityBC<E> {     public virtual Task Save()     {         return repository.Save();     } } 

This will be slightly more efficient, as it doesn't involve a state machine being created for very little reason - but more importantly, it's simpler.

Any async method where you have a single await expression awaiting a Task or Task<T>, right at the end of the method with no further processing, would be better off being written without using async/await. So this:

public async Task<string> Foo() {     var bar = new Bar();     bar.Baz();     return await bar.Quux(); } 

is better written as:

public Task<string> Foo() {     var bar = new Bar();     bar.Baz();     return bar.Quux(); } 

(In theory there's a very slight difference in the tasks being created and therefore what callers could add continuations to, but in the vast majority of cases, you won't notice any difference.)

like image 92
Jon Skeet Avatar answered Sep 22 '22 17:09

Jon Skeet