【问题标题】:Why does my new .Net 4.0 EF application randomly lock up?为什么我的新 .Net 4.0 EF 应用程序随机锁定?
【发布时间】:2011-12-01 07:47:23
【问题描述】:

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

用户报告了应用程序“偶尔冻结”(他们都使用 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...

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

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

我应该补充一点,当这种情况发生在我身上时,我正在本地 PC 上运行,所以我是唯一的用户,并且只有一个打开应用程序的窗口..

虽然,我完全被难住了!

【问题讨论】:

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


    【解决方案1】:

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

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

    我希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      听起来请求执行时间太长。除非您使用 http 管道(无论如何都不能很好地支持),否则 Web 浏览器只允许与单个 Web 服务器保持两个并发连接。但是,我的经验是,这是每个浏览器,而不是每个标签。

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

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

      如果您认为这与 EF 有关,您可以阅读如何避免在多线程环境中锁定(因为 Web 应用程序非常多线程,但这通常在生产环境中启动)。

      【讨论】:

      • 我应该补充一点,当上面发生这种情况时,我正在本地 PC 上运行,所以我是唯一的用户,并且只有一个打开应用程序的窗口..
      • 我刚刚意识到...我们将“httpRuntime executionTimeout”值设置为“1200”(20 分钟,对吗?)。如果我理解正确,并且问题在于请求延迟,我不能降低这个值并且页面会更快地放弃吗?这是否也会释放或重置这两个 Web 浏览器连接之一?
      • 即使你是唯一的用户,你也可以触发并发请求,但在生产中更常见。将 executionTimeout 设置为 20 分钟听起来真的过分了,所以是的,你可以降低它。但是,您也应该找到问题的根源,因为即使是很小的锁定(比如 90 秒)也会很烦人,更不用说损坏的功能了。
      • 我没有运气追踪到这一点。但是,我可以让它经常失败。性能计数器看起来不错。就像浏览器刚刚“过载”一样。当我浏览到具有最大查询结果的页面时,通常会在一段时间后触发它。我总是可以在另一台 PC 甚至同一台 PC 上的另一个浏览器上正常使用该应用程序。但是,一个浏览器窗口总是会在一段时间后停止响应。 :(
      • 我确实认为这可能是一个锁定问题。当用户“点击太快”时,它似乎更频繁地发生。换句话说,我认为用户可能在他们之前的查询完成之前发起了一个额外的请求(查询或其他语句......甚至“更新”)。这是你说的场景吗?第二个会导致一个新线程吗?
      【解决方案3】:

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

      第 1 步 - 环境可见性

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

      此外,在 IIS 和 DB 中添加总请求时间计数器(这样您就可以看到它在挂起时不断攀升)。

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

      第 2 步 - 重现问题

      通常此时,应用程序会意识到您可以看到它并开始表现完美。 ;) 停止并确保您仍然可以重现该问题。

      第 3 步 - 将数据库排除在外

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

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

      第 4 步 - 复​​制和测量

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

      【讨论】:

      • 当这件事发生在我身上时...我正在运行每个 LOCAL、SQL、IIS、浏览器等...
      • 我似乎找不到 IIS 当前请求计数器...我在“W3SVC_W3P”下看到一个名为“活动请求”的计数器。 (使用 IIS 7.5 运行 Windows 7 64 位...)我将在我有时使用的 VM 上运行 Fiddler 和 wb 客户端,以帮助隔离事物,以便我可以更轻松地过滤我在 SQL 探查器中寻找的内容。 .
      • 我没有运气追踪到这一点。但是,我可以让它经常失败。性能计数器看起来不错。就像浏览器刚刚“过载”一样。当我浏览到具有最大查询结果的页面时,通常会在一段时间后触发它。我总是可以在另一台 PC 甚至同一台 PC 上的另一个浏览器上正常使用该应用程序。但是,一个浏览器窗口总是会在一段时间后停止响应。 :(
      【解决方案4】:

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

      尝试使用 SQL 分析器来跟踪活动,并隔离哪些进程正在运行很长时间。

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

      【讨论】:

      • 我应该补充一点,当上面发生这种情况时,我在本地 PC 上运行,所以我是唯一的用户,并且只有一个窗口打开应用程序..
      • 没关系,我在想也许一个数据库操作正在锁定另一个数据库操作,即使在单个用户会话中也是如此。
      【解决方案5】:

      我有关于这个问题的新信息。

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

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

      我在每个页面上实现了一个 Ajax“加载”动画,防止用户在上一个请求完成之前点击按钮,这大大减少了用户遇到的“冻结”次数。

      虽然,它仍然经常发生。

      【讨论】:

      • 您可以编辑原始问题以包含此信息。这不属于答案帖子。
      猜你喜欢
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多