代码之家  ›  专栏  ›  技术社区  ›  nickytonline

JavaScript中的Web服务调用导致浏览器中的白屏死亡(WSOD)

  •  1
  • nickytonline  · 技术社区  · 15 年前

    • AJAX控件工具包
    • 查询1.3.2
    • web服务
    • Windows Server 2003 SP1上的IIS6
    • SP1 SQLServer2005SP3站点是SSL
    • Infragistics Web Components 2009第2卷(使用非合气道控件)、UltraWebGrid和树控件是主要使用的控件。

    问题是: 我在IE7/8中得到了死亡的白屏(WSOD)。基本上,我有一个页面,它有一个左窗格,其中有一个AJAXControl工具箱Accordion控件,每个Accordion窗格的内容都是一个Infragistics树控件。右窗格是一个 <div> 有一个 <iframe>

    <iframe> ,单击左窗格中的菜单项时,将加载包含一个或多个UltraWebGrid控件的页面。网格都有一个模板按钮列。单击网格行的“编辑”按钮时,将打开一个用于编辑记录的弹出窗口。这可以正常工作大约十次,然后在第十次(有时更早),弹出窗口打开与地址栏中的正确网址,但网页永远不会加载。

    我们有一个应用程序,它使用一个弹出窗口来更新记录。大多数情况下,当您点击[Edit]按钮编辑记录时,弹出窗口会打开并加载更新页面。但是,编辑记录一段时间后,弹出窗口会突然打开,但它保持空白,只是挂起。URL位于地址栏中。

    加载Fiddler时,我注意到更新页面的请求从未发送过,这使我相信这是客户端的某种锁定。如果我将弹出窗口中的相同URL复制到新的浏览器窗口中,页面通常可以正常加载。

    观察: -由于请求从未发送到服务器,因此它肯定与客户端或浏览器相关。 -只有当站点上有一些貌似的流量时才会发生,这很奇怪,因为这似乎包含在客户端代码中 -每隔几秒钟就会在后台调用一个web服务,检查用户是否登录,但这不会导致冻结。

    我在这儿真是不知所措。我在google上搜索过WSOD,但似乎没有多少与我的特定WSOD相关。有什么想法吗?

    真正的问题是什么

    因此,内存泄漏(尽管我已经在客户端封存了一些)不是问题所在。问题是在客户端进行web服务调用。有一种方法检查用户是否每4秒登录一次(以与另一个窗口同步),然后有web服务调用来获取用户对弹出窗口和网格状态的首选项。据我所知,web服务必须是异步的。我通过JavaScript调用success/fail回调来假设它们是异步的,但实际上不是。从客户端/浏览器的角度来看,它们是异步的,但是从服务器端来看,对web服务的调用是进行的,并且在完成时返回,因为连接的数量有限,因此会占用任何其他操作。

    那么,让web服务方法异步化的最简单方法是什么呢?web服务是否需要转换为WCF web服务,或者我是否可以使用现有的ASP.NET web服务调用?

    从历史的角度来看,我认为问题的根源是:

    我做了另一个没有附加组件的测试, iexplore.exe -extoff src

    我还做了一些内存泄漏调查: -据我所知,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 ):

      $(文档).ready(函数(){ 功能清除(d){ var a=d.属性,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

    1 回复  |  直到 15 年前
        1
  •  0
  •   David    15 年前

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

    如果使用的是.ashx,则必须使用一个接口才能访问会话状态,默认值为off,因此请检查是否添加了其中一个接口,如果可能,请删除:

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

        <%@ Page language="c#" Codebehind="WebForm1.aspx.cs"
    AutoEventWireup="false" Inherits="WebApplication1.WebForm1"
    EnableSessionState="false" %>