为什么我的新.Net 4.0 EF应用程序会随机锁定?

时间:2011-02-27 10:40:09

标签: c# .net asp.net entity-framework-4 iis-7.5

我最近推出了一个新的ASP .Net应用程序。此应用程序使用.Net 4.0和实体框架4.它是一个“基本”CRUD应用程序。我几乎专门使用EntityDataSource进行数据访问。

用户报告了应用程序的“ocassional freeze”(他们都使用IE 8)。如果用户关闭他的浏览器并开始备份,那么该应用程序就可以了。它可能每天发生一次或两次,通常对于重度用户。 (所以,我一直倾向于记忆泄漏或其他一些资源限制。)

直到不久前,我从未见过这种情况。它不会在客户端PC和服务器上的事件日志中留下任何内容。此外,IIS错误日志或SQL日志中没有任何内容。

不久前,我终于明白了。我正在将所有EntityDataSource切换为每页使用一个Object Context。我下载了EF Profiler(它似乎是一个很棒的产品)并且它指出我在我的许多页面上使用多个对象上下文,因为它们中的许多都有多个EntityDataSource。所以,我正在清理所有这些并测试每一页,当看到...... IE停止加载页面!

首先,页面开始缓慢加载(这是我已经修改为使用单个对象上下文的页面,所以尽管我仍然认为我需要在所有页面中实现这种“单例”模式,我猜它不是罪魁祸首!无论如何..),然后在某些时候我收到了:

消息:Sys.WebForms.PageRequestManagerTimeoutException:服务器请求超时。

但事件日志中没有任何内容。我还检查了IIS网络日志,但我没有看到任何内容,但是用肉眼很难阅读,我可能需要下载解析器以确保其中没有任何内容。

无论如何,我决定启动另一个窗口并导航到我的应用程序,确定该窗口工作正常,没有问题。我回到窗口停止响应,刷新它,等待...转到我的应用程序的主页(这基本上只是一些静态的HTML ..没有...)。接下来,我在窗口中打开了一个当前冻结的新选项卡,该选项卡正常工作。所以,我回到窗口,无法再从我的应用程序加载页面并尝试其他一些网站.... espn.com加载正常,msn.com加载正常,然后我输入我的应用程序主页的URL(并尝试了我的应用程序中的其他页面)和没有。 IIS甚至没有记录其日志文件中的尝试(就像IE刚刚决定不再为我的localhost做“获取”!)。最后,在等待一段时间后(当我输入这篇文章时)我现在在该窗口中显示此错误消息:

Internet Explorer无法显示网页。您可以尝试:问题可能是由各种问题引起的,包括:BLAH BLAH BLAH ......

所以,我跳回到那个窗口,它仍然可以很好地浏览互联网网站。但是,当我尝试去我的应用程序中的任何页面时,我再次没有(在选项卡中旋转蓝色圆圈)。所以,我再次在同一个浏览器中启动一个新选项卡,我可以很好地浏览我的应用程序。

我的应用程序对这个浏览器实例做了什么,它将不再允许它加载任何页面(事实上,它似乎甚至没有在任何应用程序页面上执行GET,因为没有什么新东西在IIS日志中...除了当我在其他选项卡和/或浏览器窗口中加载页面工作正常时,所以日志记录仍在工作......)?我会永远感激能够帮助我解决这个问题的人。我不确定它会带来多大的好处,但是我会留下这个浏览器窗口,因为有人可以告诉我一些事情来尝试诊断这个问题。我觉得我已经接近搞清楚了。我终于有了一个行为不端的窗口。我害怕关闭窗口或在应用程序上进行新的构建,直到我得到一些关于尝试的好的输入....

我应该补充说,当我遇到这种情况时,我在我的本地PC上运行,所以我是唯一的用户,只有一个窗口可以打开应用程序..

虽然,我完全难过!

5 个答案:

答案 0 :(得分:2)

我们遇到了同样的问题,似乎通过将以下JavaScript添加到带有ajax的所有页面来修复它:

window.onunload = abortRequest;
function abortRequest() {
   Sys.WebForms.PageRequestManager.getInstance().abortPostBack();
} 

我希望这有帮助!

答案 1 :(得分:1)

听起来像请求执行时间太长。只允许Web浏览器将两个并发连接保留到单个Web服务器,除非您使用http流水线(无论如何都不支持)。但是,我的经验是,这是每个浏览器,而不是每个标签。

这就是您的日志中没有显示任何内容的原因,因为您的浏览器从不会发起请求,因为它正在等待页面完成加载,然后才能获取其他页面。我会开始研究在锁定之前发起的最后一个请求,它可能是由于某种原因锁定而且永远不会完成的页面。

ASP.NET只使用一个线程,只要所有请求都是顺序的。一旦同时启动两个请求,就会启动一个新线程(调用HttpApplication上的Init()),如果你在Init()上执行时髦的东西,这可能会导致间歇性错误。

如果您认为这与EF有关,您可能会了解如何避免在多线程环境中锁定(因为Web应用程序非常多线程,但这通常会在生产环境中发挥作用)。

答案 2 :(得分:1)

唉,我感觉到你的痛苦 - 我讨厌这些类型的问题。当这样的事情发生时(这在某种程度上适合你的情况),这是我的分而治之的过程:

第1步 - 环境可见性

让自己进行设置,以便大致了解系统内部。设置性能监视器,并添加几个重要的计数器(IIS当前请求,ASP.NET当前请求,SQL Server - 活动事务)。这里使用“活动请求/事务”计数器的想法是您想要找出系统的哪个部分持有请求。

此外,在IIS和数据库中添加总计请求时间的计数器(这样您就可以看到它在某些东西悬挂时攀爬)。

在您的客户端PC上,设置Fiddler。

第2步 - 重现问题

通常在这一点上,应用程序意识到你可以看到它并开始表现完美。 ;)停止并确保您仍然可以重现该问题。

第3步 - 将DB从等式中取出

在您的应用程序中创建4个页面:

  1. 不会通过ASP.NET运行时引擎的静态HTML文件(.htm)。这是原始IIS的基准。
  2. 没有技巧的ASPX页面(没有数据库访问,没有处理,只是一个ASP.NET可以吐出的简单页面)
  3. ASPX页面有一个简单的数据库调用(一些大小,可能只做一个大查询或其他)
  4. 包含一些复杂事务(多个查询等)的ASPX页面
  5. 第4步 - 重现和衡量

    因为一旦你看到这个问题可能会非常明显,找到你的性能指标和Fiddler的瓶颈。您的问题听起来像是一个间歇性的连接问题(客户端和Web服务器或Web服务器/ SQL之间),特别是如果IE给您“页面无法显示”错误,但您应该在Fiddler中看到。在服务器端,您应该看到其中一个性能计数器挂起。

答案 3 :(得分:0)

好吧,听起来应用程序正在等待数据库操作完成但被锁定,可能是因为另一个操作。

尝试使用SQL事件探查器跟踪活动,并隔离长时间运行的进程。

您可以使用跟踪视图中的SPID列区分请求,它包含应用中每个会话的唯一ID号。

答案 4 :(得分:0)

我有关于此问题的新信息。

该应用程序使用集成身份验证。这会导致每个请求在IE发送凭据之前返回(两次)拒绝访问。

我不禁想知道这是否会导致“超时”。

我在每个页面上实现了一个Ajax“加载”动画,阻止用户点击按钮,直到上一个请求完成,并且大大减少了用户遇到的“冻结”量。

虽然,它仍然经常发生。