我在ASP.Net MVC 5应用程序中遇到异步控制器问题。 我使用的是Entity Framework 6 Code First方法。
我有一个方法
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
});
}
}
我这里有两个异步方法。我通过MiniProfiler分别测量了它们。它们需要大约85毫秒。
但是在我的方法中,我使用Task.WhenAll()运行它们。我相信它以异步方式执行Db查询,并且两者都需要大约85-90毫秒。但它需要~170-180。所以我有异步方法同步运行(彼此跟随)。
我认为这是因为背景。当我删除上下文查询并使用HttpClient调用许多api方法时,我有一个测试。它需要时间等于更长的时间(3 api调用,每个~500 ms。完全方法需要~600 ms)。我相信可以异步执行EF方法。
有谁知道解决方案
答案 0 :(得分:7)
这实际上不应该工作,而是抛出异常。我猜测第一个查询在第二个查询开始之前完成。
EF6 doesn't support multiple async operations on the same context.
每个查询都await
(因此他们不会同时运行),或者为每个查询使用不同的上下文。
答案 1 :(得分:0)
我发现了问题。
原因是MiniProfiler.EF6。 1)为了测量我的sql问题,我使用MiniProfiler.EF6。这个框架避免了并发sql查询,即使我使用不同的EF DBContext。
2)我禁用MiniProfile.EF6并运行我的应用程序。关于ken2k提到的我有一个例外。为了避免这种异常,我遵循这个答案 EF6 doesn't support multiple async operations on the same context.
3)我测量Dapper和并发SQL查询。我在测试中使用了单个SQLConnection进行异步查询。我有结果:
a)如果我使用SqlConnection进行Dapper,则查询执行
异步(并行)
b)如果我使用来自的ProfiledDbConnection MiniProfiler然后Dapper执行查询跟随彼此(不是 平行)