How to make Entity Framework execute asynchronousl

2019-05-10 00:54发布

I have problem with asynchronous controller in ASP.Net MVC 5 application. I'm using Entity Framework 6 Code First approach.

I have a method

public async Task<ActionResult> Index()
{
    using(var context = new MyDbContext())
    {
        var eventsTask = context.Events
            .Where(e => e.Enable)
            .ToListAsync();

        var countTask = context.Users
            .CountAsync();

        await Task.WhenAll(eventsTask, countTask);
        return View(new ViewModel()
        {
            Events = eventsTask.Result, 
            Count = countTask.Result
        });
    }
}

I have two asyncronous methods here. I have measured each of them separately via MiniProfiler. They takes ~85 ms.

But in my method I run them using Task.WhenAll(). I believe it executes Db queries asynchronously and should take about ~85-90 ms for both. But it takes ~170-180. So I have got asynchronous methods run synchronously (following each other).

I think it is because of context. I have a test, when I remove context queries and call many api methods using HttpClient. It takes time equals to longer of them (3 api calling, ~500 ms each of them. Totally method takes ~600 ms). I believe that It is possible to execute EF methods asynchronously.

Does anyone know the solution

2条回答
一夜七次
2楼-- · 2019-05-10 01:51

I found the problem.

The reason is a MiniProfiler.EF6. 1) To measure my sql question I use MiniProfiler.EF6. This framework avoid concurrent sql queries even I use different EF DBContext.

2) I disable MiniProfile.EF6 and run my application. I have got an exception about that ken2k mentioned. To avoid this exception I follow this answer EF6 doesn't support multiple async operations on the same context.

3) I measure Dapper and concurrent SQL queries. I have used a single SQLConnection for asyncronous queries in my tests. I have had the results:

a) if i use SqlConnection for Dapper then queries execute
asynchronous (parallel)

b) if i use ProfiledDbConnection from
MiniProfiler then Dapper execute queries follow each others (not
parallel)

查看更多
狗以群分
3楼-- · 2019-05-10 01:53

This shouldn't even work actually, but throw an exception instead. I'm guessing the first query completes before the second one even starts.

EF6 doesn't support multiple async operations on the same context.

Either await each query (so they won't run concurrently), or use a different context for each query.

查看更多
登录 后发表回答