asp.net 一页上的 mvc 查询太多 entity framework 并行?

asp.net mvc too many queries on one page entity framework parallel?

我正在使用 asp.net mvc 5 构建网站。

目前我正在使用依赖注入将每个请求的 dbcontext 注入我的控制器。

但是 EF 不是线程安全的,因此不能在并行查询中使用一个 dbcontext。

是否值得对我的网站进行更改,让这个页面像这样使用 smt?

using(var ctx = new dbcontext) {
    //creating a task query like tolistasync
}

using(var ctx2 = new dbcontext) {
    //creating a task query like tolistasync
}

using(var ctx3 = new dbcontext) {
    //creating a task query like tolistasync
}
.
.
.
.
.
.
.
using(var ctx20 = new dbcontext) {
    //creating a task query like tolistasync
}

然后:

 Task.WhenAll(t1,t2,t3,......,t20)

或者我应该只为每个请求使用一个 dbcontext 并做这样的事情:

 var query1result = await query1.ToListAsync();
 var query2result = await query2.ToListAsync();
 var query3result = await query3.ToListAsync();
 var query4result = await query4.ToListAsync();
 .
 .
 .
 .
 .
 var query19Result = await query19.ToListAsync();
 var query20Result = await query20.ToListAsync();

在第一种情况下,会打开和关闭与数据库的连接。

一秒钟内会有一个连接,但一切都是按顺序发生的

哪种情况更好,为什么?

首先,问问自己——你真的有性能问题吗?如果没有 - 像往常一样做 - 在一个 DbContext 中。这是最简单和非常安全的方法。

如果你有问题?让我们试试:

如果您的查询是只读的,您可以 运行 多个线程并行。创建新的 DbContext 和打开新的连接 - 这不是一个常见的大问题。此外,您可以使用 AsNoTracking 调用所有只读查询。因此,EF 不会在上下文中缓存实体。

但是,请三思。在并行执行代码中调试和发现问题更加困难。所以,你的操作一定很简单。

如果您确实需要处理很多查询,您可以 运行 并行处理它们。我会使用 Parallel.ForEach.

But EF is not thread safe so one dbcontext can't be used in parallel queries.

“线程安全”与“支持多并发操作”完全不同。

Is it worth to make change to my website so just this page use smt like this?

which case is better an why?

只有你能回答这个问题。

但是,有一些一般指导。

首先,对数据库的操作通常是 I/O-bound,而不是 CPU 绑定的。请注意,此规则有很多例外情况。

其次,如果 all/most 操作正在访问同一个数据库,则在文件级别肯定存在争用。

第三,如果数据库位于传统(即非固态)硬盘驱动器上,则在磁盘盘片级别上会发生更多争用。

所以,这就是说 如果 你的后端只是一个普通的 SQL 服务器,那么你可能看不到任何好处(即更快响应时间)来自服务器处于正常负载时的并发数据库操作。事实上,在这种情况下,您可能根本看不到异步数据库调用的任何好处(与同步调用相比)。

但是,如果您的后端更现代,比如 Azure SQL 实例(尤其是 SSD 上的一个 运行),那么并发数据库操作确实可以加快您的请求速度。