Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the difference between this two async call in EF?

I have seen a new feature in EF6, the async methods. I find an example.

This first way is the normal call, with EF5 for example:

public Store FindClosestStore(DbGeography location)
{
    using (var context = new StoreContext())
    {
        return (from s in context.Stores
           orderby s.Location.Distance(location)
           select s).First();
    }
}

And the new call, with async method in EF6.

public async Task<Store> FindClosestStore(DbGeography location)
{
    using (var context = new StoreContext())
    {
        return await (from s in context.Stores
            orderby s.Location.Distance(location)
            select s).FirstAsync();
    }
}

However, I can do the following (the syntaxis is aprox, I do it by memory):

public async Task<Store> MyAsyncMethod(DbGeography location)
{
     return await Task.Run(() => FindClosestStore());
}

I mean, that I can use Task.Run to call the first method, that is no async, to wait the result. At the moment, is the way that I use to call async any method, not only EF. This is an async call too or the truly async call is when I use the EF6 async method?

Why the needed of the async methods in the new version of EF6? Only for simplicity?

like image 395
Álvaro García Avatar asked Nov 12 '12 10:11

Álvaro García


1 Answers

The difference here is how the code awaits.

In the of this code:

public async Task<Store> FindClosestStore(DbGeography location)
{
    using (var context = new StoreContext())
    {
        return await (from s in context.Stores
            orderby s.Location.Distance(location)
            select s).FirstAsync();
    }
}

EF will issue a query against the database, and return.

Once the result have returned, the task will complete and the await block will continue to execute.

That is, there is no thread in .NET itself that is waiting for the response. There is (hopefully) a lower level callback from the db driver that notifies .NET when the result has arrived.

(This is at least how other async IO works in .NET, and I assume the same for ADO.NET async)

In the other case:

public async Task<Store> MyAsyncMethod(DbGeography location)
{
     return await Task.Run(()=> FindClosestStore());
}

There will be a thread waiting for the response from the DB. that is, you will have blocking IO but it will be hidden from the consumer with your task.run trick.

Both cases will behave the same for the consumer, the difference is that you are hogging up resources in the last example.

like image 76
Roger Johansson Avatar answered Oct 20 '22 00:10

Roger Johansson