为什么我的新.Net 4.0 EF应用程序会随机锁定?
我最近推出了一个新的ASP .Net应用程序。此应用程序使用.Net 4.0和实体框架4.它是一个“基本”CRUD应用程序。我几乎完全使用EntityDataSource进行数据访问。为什么我的新.Net 4.0 EF应用程序会随机锁定?
用户已经报告了应用程序的“ocassional freeze”(它们都使用IE 8)。如果用户关闭他的浏览器并重新开始,那么应用程序就没问题。它可能每天发生一次或两次,通常是重度用户。 (所以,我一直倾向于内存不足或某种其他类型的资源限制。)
直到就在前一段时间,我从未见过这种情况。它不会在客户端PC和服务器上的事件日志中留下任何内容。此外,IIS错误日志或SQL日志中没有任何内容。
不久前,我终于发生了。我将所有的EntityDataSources切换为每页使用一个对象上下文。我下载了EF Profiler(这似乎是一个很棒的产品),并指出我在很多页面上使用了多个对象上下文,这是因为它们中的很多都有多个EntityDataSource。所以,我正在清理所有这一切,并测试每一页,当你看到.... IE停止加载页面!
起初,页面开始加载缓慢(这是一个页面,我已经修改为使用单个对象上下文,所以尽管我仍然相信我需要在我的所有页面中实现这种“单例”模式,但我猜猜它不是罪魁祸首!无论如何..),然后在某些时候我收到:
消息:Sys.WebForms.PageRequestManagerTimeoutException:服务器请求超时。
仍然没有在事件日志中。我也检查了IIS网络日志,但没有看到任何内容,但用肉眼很难阅读,我可能不得不下载解析器以确保没有任何内容。
无论如何,我决定启动另一个窗口并导航到我的应用程序,并确定窗口工作正常,没有问题。我回到停止响应的窗口,刷新它,等待...去我的应用程序的主页(这基本上只是一些静态html ..没有..)。接下来,我在当前被冻结的窗口中打开了一个新选项卡,该选项卡正常工作。所以,我回到窗口,不能再从我的应用程序加载页面,并尝试一些其他网站.... espn.com加载罚款,msn.com加载罚款,然后我输入我的应用程序主页的URL(并尝试在我的应用程序中的其他页面),但没有。 IIS甚至不会在其日志文件中记录尝试(就像IE刚刚决定不再做“获取”我的本地主机!)。最后,在等待一段时间(当我输入这篇文章的时候),我现在在那个窗口中有这个错误信息:
Internet Explorer无法显示网页。你可以尝试:这个问题可能是由各种问题引起的,包括:BLAH BLAH BLAH ...
所以,我跳回到那个窗口,它仍然可以浏览Internet站点。但是,当我尝试访问我的应用程序中的任何页面时,我再次遇到任何问题(在标签中旋转蓝色圆圈)。所以,我再次在同一浏览器中启动一个新选项卡,并且可以很好地浏览我的应用程序。
我的应用程序对这个浏览器实例做了什么,它将不再让它加载它的任何页面(事实上,它似乎甚至没有在任何应用程序页面上进行GET,因为没有任何东西新的IIS日志...除了当我加载页面在这些其他标签和/或浏览器窗口工作正常,所以日志记录仍在工作......)?我将永远感激可以帮助我解决这个问题的人。我不确定它会有什么好处,但我会离开这个浏览器窗口,因为有人可以告诉我一些事情来尝试诊断这个问题。我觉得我很接近想出来。我终于有了一个窗户,这是行为不端。我害怕关闭窗口或在应用程序上做一个新的内部版本,直到我得到一些好的输入来尝试......
我应该补充一点,当这发生在我身上时,我在本地PC上运行,所以我是唯一的用户,并只有一个窗口开放的应用程序..
虽然,我完全难倒!
听起来像一个请求只需要很长时间才能执行。除非使用http流水线(反正不支持),否则只允许Web浏览器保持两个并发连接到单个Web服务器。不过,我的经验是,这是每个浏览器,而不是每个标签。
这就是为什么没有在你的日志显示出来,因为你的浏览器,因为它在等待网页加载完成,然后才能读取另一页从未发起的请求。我会开始研究在锁定之前启动的最后一个请求,它可能是由于某种原因锁定并永不完成的页面。
只要所有请求都是顺序的,ASP.NET就只使用一个线程。只要同时触发两个请求,就会启动一个新线程(调用HttpApplication上的Init()),如果您在Init()上做了时髦的事情,则会导致间歇性错误。
如果您认为这与EF有关,您可以阅读如何避免在多线程环境中锁定(因为Web应用程序非常多线程,但通常会在生产环境中启用)。
呃,我感觉到你的痛苦 - 我讨厌这些类型的问题。下面是当这样的事情发生了(有点适应您的情况)我的鸿沟正征服过程:
第1步 -
让自己设立这样你就可以在你的系统里面大致看到环境的可见性。设置性能监视器,并添加一些重要的计数器(IIS当前请求,ASP.NET当前请求,SQL Server - 活动事务)。这里的“主动请求/事务”计数器的想法是你想知道系统的哪一部分正在持有请求。
此外,添加在IIS和DB总请求时间计数器(所以你可以看到它攀爬的东西挂在)。
在您的客户端PC上设置Fiddler。
第2步 - 重现问题在这一点上
通常,应用程序实现,你可以看到它,并开始完美表现。 ;)停止并确保您仍然可以重现该问题。
第3步 - 以DB的方程
创建应用程序中的4页:
- 静态HTML文件名(.htm)将不通过ASP.NET运行时去发动机。这是原始IIS的基准。没有窍门
- ASPX页面(没有数据库访问,没有处理,只是一个简单的页面,ASP.NET可以吐出)
- 一个简单的数据库调用(有些大小的ASPX页面,也许做一个大的查询或东西),还有一些复杂的交易
- ASPX页面(多次查询等)
第4步 - 重现和测量
因为这个问题可能会是很明显的,一旦你可以看到它,找到瓶颈w ith你的表演柜台和Fiddler。你的问题听起来像你可能有一个间歇性的连接问题(无论是客户端和Web服务器或Web服务器/ SQL),特别是如果IE给你的“页面无法显示”的错误,但你应该看到在提琴手。在服务器端,您应该看到其中一个性能计数器挂起。
当这发生在我身上......我正在运行LOCAL,SQL,IIS,浏览器等...... – Shayne 2011-02-27 20:06:59
你的性能计数器现在说什么? – Brandon 2011-02-27 20:11:00
我似乎无法找到IIS当前请求计数器......我在“W3SVC_W3P”下看到一个名为“活动请求”的文件。 (使用IIS 7.5运行Windows 7 64位...)我将在有时使用的虚拟机上运行Fiddler和wb客户端,以帮助隔离事件,以便我可以更轻松地过滤我在SQL Profiler中查找的内容。 – Shayne 2011-02-27 20:37:41
我有关于此问题的新信息。
该应用程序使用集成身份验证。这会导致每次请求都会返回(两次),并在IE发送凭据之前拒绝访问。
我不禁想知道这是什么可能导致“暂停”。
我在每个页面上实现了一个Ajax“加载”动画,以防止用户点击按钮,直到前一个请求完成,并大大减少了用户遇到的“冻结”的数量。
虽然,它还是经常发生。
您可以编辑您的原始问题以包含此信息。这不属于答复帖子。 – 2011-05-18 18:20:04
我们有同样的问题,似乎与阿贾克斯添加以下JavaScript来的所有页面进行修复:
window.onunload = abortRequest;
function abortRequest() {
Sys.WebForms.PageRequestManager.getInstance().abortPostBack();
}
我希望这有助于!
我应该补充一点,当我在上面遇到这种情况时,我在本地PC上运行,所以我是唯一的用户,只有一个窗口可以打开应用程序.. – Shayne 2011-02-27 19:34:37
我刚刚意识到一些事情......我们有“httpRuntime executionTimeout”值设置为“1200”(20分钟,对吧?)。如果我理解正确,并且问题与请求混淆,我是不是可以降低此值,并且页面会更快放弃?这是否也会释放或重置这两个Web浏览器连接之一? – Shayne 2011-02-28 01:19:12
即使您是唯一的用户,您也可以触发同时发出的请求,但是它在生产中更常见。执行超时设置为20分钟听起来真的太过分了,所以是的,你可以降低它。然而,你也应该找到问题的根源,因为即使是很小的锁定(比如90秒)也会令人讨厌,更不用说破坏的功能了。 – jishi 2011-02-28 09:19:57