这是规格:
- 使用 ASP.NET AJAX 的 ASP.NET 3.5
- AJAX 控制工具包
- jQuery 1.3.2
- 网页服务
- Windows Server 2003 SP1 上的 IIS6
- SP1 SQLServer 2005 SP3 站点是 SSL
- Infragistics Web 组件 2009 卷。2(使用非合气道控件),UltraWebGrid和Tree控件是主要使用的。
这就是问题所在:我在 IE 7/8 中获得了白屏死机 (WSOD)。基本上,我有一个页面,它有一个左窗格,其中有一个 AJAXControl Toolkit Accordion 控件,其中每个手风琴窗格的内容都是一个 Infragistics 树控件。右窗格是一个<div>
根据<iframe>
在左菜单窗格中单击的内容重新加载其内容的窗格。
在 中<iframe>
,当您单击左窗格中的菜单项时,会加载一个包含一个或多个 UltraWebGrid 控件的页面。网格都有一个模板按钮列。当您单击网格行的编辑按钮时,将打开一个用于编辑记录的弹出窗口。这可以正常工作大约十次,然后在第十次(有时更早)时,弹出窗口会在地址栏中打开正确的 URL,但页面永远不会加载。
我们有一个应用程序,它使用一个弹出窗口来更新记录。大多数情况下,当您单击 [编辑] 按钮编辑记录时,弹出窗口会打开并加载更新页面。但是,在编辑记录一段时间后,突然弹出窗口会打开,但它保持空白并挂起。URL 在地址栏中。
加载 Fiddler 我注意到更新页面的请求从未发送过,这让我相信这是客户端的某种锁定。如果我将弹出窗口中的相同 URL 复制到新的浏览器窗口中,页面通常可以正常加载。
观察: - 由于请求永远不会发送到服务器,它肯定是客户端或浏览器相关的东西。- 仅当网站上有一些看起来很奇怪的流量时才会发生,因为这似乎包含在客户端代码中 - 每隔几秒就会在后台调用一个 Web 服务,检查用户是否登录,但这不会导致冻结。
我在这里真的很茫然。我用谷歌搜索了 WSOD,但似乎与我的特定 WSOD 无关。有任何想法吗?
真正的问题是什么
结果证明内存泄漏(尽管我已经在客户端密封了一些)不是问题。问题是在客户端进行的 Web 服务调用。有一个检查用户是否每 4 秒登录一次(以与另一个窗口同步),然后有 Web 服务调用来获取用户对弹出窗口和网格状态的首选项。根据我的阅读,Web 服务必须是异步的。我通过使用成功/失败回调从 JavaScript 调用它们来假设它们是异步的,但实际上并非如此。从客户端/浏览器的角度来看,它们是异步的,但从服务器端来看,由于连接数量有限,对 Web 服务的调用会在它完成阻止任何其他操作时返回并返回。
那么使 Web 服务方法异步的最简单方法是什么?Web 服务是否需要转换为 WCF Web 服务,或者我可以使用现有的 ASP.NET Web 服务调用吗?
出于历史目的,这就是我最初认为的问题所在:
我无法在本地或我们的测试服务器上重现此内容。但是,我让 Fiddler 来模拟调制解调器的速度,突然间我可以在本地 PC 上复制 WSOD。因此,在打开导致其阻塞的弹出窗口时,至少在我的测试环境中,它似乎是一个缓慢或暂时缓慢的连接。
我在没有附加组件的情况下进行了另一次运行 IE 的测试iexplore.exe -extoff
,但最终得到了相同的结果。我还修复了每次 iframe 的 URL 更改时都会重新创建页面上的 iframe 的问题。我的部分逻辑被省略了。现在 iframe 只创建一次。之后,src
当我想加载新内容时,只有属性会更新......我的傻瓜。我注意到 JavaScript 闭包中有一些挥之不去的窗口引用,所以现在当我完成它们时,它们在闭包中显式设置为 null。
我还进行了一些内存泄漏调查:-据我所知,我在 DOM 和 JavaScript 或此处提到的其他泄漏模式中没有任何循环引用,http://www.ibm.com/developerworks/web /library/wa-memleak/?S_TACT=105AGX52&S_CMP=cn-a-wa
我已经为 IE 内存泄漏添加了 Crockenator 的清除代码(参见http://www.crockford.com/javascript/memory/leak.html):
$(document).ready(function() { function purge(d) { var a = d.attributes, i, l, n;
if (a) { l = a.length; for (i = 0; i < l; i += 1) { if (a[i]) { n = a[i].name; if (typeof d[n] === 'function') { d[n] = null; purgeCount++; } } } } a = d.childNodes; if (a) { l = a.length; for (i = 0; i < l; i += 1) { purge(d.childNodes[i]); } } } $(window).unload(function() { purge(document.body); //alert("purge count: " + purgeCount); });
});
我的改进都没有解决这个问题。在我的本地测试场景中。有任何想法吗?任何人?任何人?布勒?
最后更新
感谢 David 指出是会话状态导致了 Web 服务中的问题。“ASP.NET 将所有请求排队到同一个‘会话’。因此,如果第一个请求阻塞太久,它将阻止任何其他排队的请求。”
所以我们最终做的是尝试使用会话状态最小化 Web 服务,但我们还添加了 Microsoft 推荐的连接数设置,请参阅http://msdn.microsoft.com/en-us/library/ff647786.aspx #scalenetchapt10_topic9