Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing my server-side WebAPI to get the benefits of async/await

Trying to understand server-side async/await use. My understanding is that it is only useful when the thread can be freed. If I have:

[HttpGet]
public async Task<IEnumerable<MyObject>> Get()
{        
     return await Task<IEnumerable<MyObject>>.Run(() => DoThingsAndGetResults());
}

IEnumerable<MyObject> DoThingsAndGetResults()
{
    // ...Do some CPU computations here...

    IEnumerable<MyObject> result = myDb.table.Select().ToList(); // entity framework

    // ...Do some CPU computations here...

    return result;
}

Will the thread ever be freed? Is Async/Await useless in this case? Is the only way to gain benefit from async/await is if I make some bigger changes and do this:

[HttpGet]
public async Task<IEnumerable<MyObject>> Get()
{        
     return await DoThingsAndGetResultsAsync();
}

async IEnumerable<MyObject> DoThingsAndGetResultsAsync()
{
    // ...Do some CPU computations here...

    IEnumerable<MyObject> result = await myDb.table.Select().ToListAsync(); // entity framework

    // ...Do some CPU computations here...

    return result;
}
like image 452
Steve Avatar asked Jan 11 '23 12:01

Steve


2 Answers

Async methods are mostly useful when you have to wait for IO operation (reading from a file, querying the database, receiving response from a web server).

It is ok to use async when, for example, your database provider supports async querying like Entity Framework 6. Though it is not very useful for CPU bound operations (calculations and so on).

See related answers at ASP.NET MVC4 Async controller - Why to use?

like image 189
Konstantin Smolyakov Avatar answered Jan 31 '23 03:01

Konstantin Smolyakov


If what you want to achieve is to free threads, the second example is better. The first one holds a thread throughout the operation.

Explanation

All that async-await does is to simply helps you write code that runs asynchronously but "looks" synchronous.

There are 2 reasons for asynchronous code:

  1. Offloading. Used mostly in GUI threads, or other "more important" threads". (Releasing threads while waiting for CPU operations to complete).
  2. Scalability. Used mainly in the server-side to reduce resource usage. (Releasing threads while waiting for IO to complete).

Unsurprisingly the reasons match your examples.

In the first example you run DoThingsAndGetResults on a different thread (using Task.Run) and waiting for it to complete asynchronously.The first thread is being released, but the second one doesn't.

In the second one you only use 1 thread at a time, and you release it while waiting for IO (Entity Framework).

like image 34
i3arnon Avatar answered Jan 31 '23 02:01

i3arnon