1

这是规格:

  • 使用 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

4

1 回答 1

0

我认为您可能在会话请求同步方面遇到问题。您是否将 Web 服务处理程序标记为需要会话状态?

ASP.NET 将所有请求排队到同一个“会话”。因此,如果第一个请求阻塞太久,它将阻止任何其他排队的请求。您可以关闭页面的会话状态以避免这种情况并真正实现异步,但是您将无法访问服务器上的会话等。

如果您使用 .ashx,则必须使用接口来访问会话状态,默认为关闭,因此请检查您是否添加了这些接口之一,并在可能的情况下删除:

public class FooHandler : IHttpHandler, IReadOnlySessionState // readonly access

public class FooHandler : IHttpHandler, IRequiresSessionState // read-write access

如果您使用的是 aspx 页面,则默认情况下它处于打开状态,您必须使用 Page 指令属性将其关闭:

    <%@ Page language="c#" Codebehind="WebForm1.aspx.cs"
AutoEventWireup="false" Inherits="WebApplication1.WebForm1"
EnableSessionState="false" %>
于 2010-06-15T13:36:10.363 回答