实体框架ToListAsync有时会挂起,有时会解决

时间:2020-07-20 13:33:00

标签: c# asp.net-mvc entity-framework async-await

我一直在努力将ASP.NET MVC仪表板页面转换为使用异步实体框架方法,并且遇到了一个问题,即有时调用会无限期挂起且没有 no 错误或挂起超过1分钟的时间,然后解决。这种行为是零星的,我还没有找到一种方法来复制它。这是我的EF电话之一,当然已经过了消毒。

注意:sqlparameters对象在上面定义。 sql是字符串形式的查询。

using (var context = new BaseDbContext())
{
    return await context.Database.SqlQuery<MyViewModel>(sql, parameters.ToArray()).ToListAsync();
}

这不是唯一会挂起的查询。有时其他查询会挂起,有些是用linq写成sql的查询,有些则使用上面的实际sql查询。

重要提示

  • 我一直在使用async / await直到我的控制器,包括控制器方法本身。
  • 有时候一切正常,所有异步调用都能正常工作,几秒钟之内就能加载所有东西。
  • “悬挂”行为是零星的。有时,它不会发生几个小时,而有时是每次启动应用程序时都会发生。

编辑 评论中的安德列斯(Andres)建议可能使我朝正确的方向看,至少要看一下。几个小时没有问题后,程序挂起时,我设法抓住了它。 SQL Profiler发现了几个RPC:Completed事件,对于非常简单的选择,这些事件花费了15-65秒以上的时间(在SSMS中运行需要花费一秒钟的时间才能完成)。所有这些都非常接近。

我已经进行了清理,将SQL在下面运行,并为添加上下文提供了开始/结束时间。

exec sp_executesql N'SELECT * FROM Reports.dbo.Customers WHERE Date = @Par1',N'@Par1 datetime',@Par1='2020-07-20 00:00:00'

开始时间:14:22:08.597

EndTime:14:22:23.197

exec sp_executesql N'SELECT * FROM Reports.dbo.Customers WHERE Date = @Par1',N'@Par1 datetime',@Par1='2019-07-20 00:00:00'

开始时间:14:22:23.267

EndTime:14:22:37.357

exec sp_executesql N'SELECT * FROM Reports.dbo.Policies WHERE Date = @Par1 OR Date = @Par2',N'@Par1 datetime,@Par2 datetime',@Par1='2020-07-20 00:00:00',@Par2='2020-06-20 00:00:00'

开始时间:14:22:38.200

结束时间:14:23:42.333

exec sp_executesql N'SELECT * FROM Reports.dbo.Policies WHERE Date = @Par1',N'@Par1 datetime',@Par1='2020-07-20 00:00:00'

开始时间:14:23:46.863

结束时间:14:23:58.773

还有一个更困难的事情,就是要花费大约6秒的时间来清理Entity Framework查询,以及在所有内容中间出现可疑的Audit Logout事件。该事件在14:18:25.753列出了开始时间,在14:23:25.770列出了结束时间。

虽然我对这些结果的解释不了解,但在我看来,问题可能是由于MVC应用程序中的所有内容都处于异步/等待状态,因此多个查询在相同的时间到达了相同的数据库表?在将仪表板转换为异步/等待之前,我认为这实际上并没有挂断。

编辑2 根据Andres的答案以及我在SQL Profiler中向跟踪中添加其他信息后所学到的知识(请参阅下面的答案下方的注释),看来表锁定是罪魁祸首,但是我一直在努力寻找有关如何解决这个问题。我猜想我们可能必须回滚到对所有内容使用同步数据库调用,而不是异步?

1 个答案:

答案 0 :(得分:1)

我正在回答添加一些图片,但我无法在评论中这样做:

正如我所说,使用SQL Server Profiler跟踪查询。这可能与数据库级别的某种阻止或问题有关。

我建议您添加一些事件以获取有关正在发生的事情的更多信息:

添加这些事件:

交易:

enter image description here

锁: enter image description here

通过这些事件,您可以检查事务何时开始以及何时结束。 您应该在中间看到RCP调用。 另外,借助Locks事件,您应该能够查看是否有任何阻塞的转换正在锁定您的查询。

如果您的RCP持续时间(请参阅专栏)过长,则问题出在SQL Server中。可能是由于表锁定。

首先检查这些事件。请注意,如果在生产环境中运行带有这些事件的事件探查器,则会消耗系统资源。

相关问题