Вызов веб-службы в JavaScript приводит к появлению белого экрана смерти (WSOD) в браузере

Вот технические характеристики:

  • ASP.NET 3.5 с использованием ASP.NET AJAX
  • AJAX Control Toolkit
  • JQuery 1.3.2
  • веб-сервисы
  • IIS6 на Windows Server 2003 с пакетом обновления 1
  • SP1 SQLServer 2005 SP3 Сайт является SSL
  • Infragistics Web Components 2009 Vol. 2 (с использованием элементов управления, отличных от айкидо), UltraWebGrid и Tree используются в основном.

Вот проблема: я получаю Белый Экран Смерти (WSOD) в IE 7/8. По сути, у меня есть страница с левой панелью, в которой есть элемент управления аккордеоном AJAXControl Toolkit, где каждый контент панели аккордеона представляет собой элемент управления дерева инфраструктуры. Правая панель <div> это имеет <iframe> чей контент перезагружается в зависимости от того, что щелкнуло в левой панели меню.

в <iframe>, страница с одним или несколькими элементами управления UltraWebGrid загружается при нажатии на элемент меню в левой панели. Все сетки имеют шаблонный столбец кнопок. При нажатии на кнопку редактирования строки сетки открывается всплывающее окно для редактирования записи. Это работает нормально около десяти раз, а затем в десятый раз (иногда раньше) открывается всплывающее окно с правильным URL-адресом в адресной строке, но страница никогда не загружается.

У нас есть приложение, которое использует одно всплывающее окно для обновления записей. В большинстве случаев, когда вы нажимаете кнопку [Редактировать] для редактирования записи, открывается всплывающее окно и загружается страница обновления. Однако, после некоторого редактирования записей, внезапно открывается всплывающее окно, но оно остается пустым и просто зависает. URL находится в адресной строке.

Загрузка Fiddler Я заметил, что запрос на страницу обновления никогда не отправляется, что наводит меня на мысль, что это какая-то блокировка на стороне клиента. Если я скопирую тот же URL, что и во всплывающем окне, в новое окно браузера, страница обычно загружается нормально.

Наблюдения: - Поскольку запрос никогда не отправляется на сервер, он определенно связан с клиентом или браузером. - Похоже, что это происходит только тогда, когда на сайте есть некоторое подобие трафика, что странно, потому что кажется, что оно содержится в коде на стороне клиента. - Каждые несколько секунд в фоновом режиме вызывается веб-служба, проверяющая, вошел ли пользователь в систему., но это не вызывает замораживание.

Я действительно в растерянности здесь. Я погуглил WSOD, но, похоже, не так уж много связано с моим конкретным WSOD. Есть идеи?

В чем проблема на самом деле

Оказывается, утечки памяти (хотя некоторые из них были закрыты на стороне клиента) не являются проблемой. Проблема заключается в том, что вызовы веб-службы выполняются на стороне клиента. Есть один, который проверяет, вошел ли пользователь в систему каждые 4 секунды (для синхронизации с другим окном), а затем выполняются вызовы веб-службы для получения пользовательских настроек для всплывающего окна и состояния сетки. Из того, что я прочитал, веб-сервисы должны быть асинхронными. Я предположил, вызывая их из JavaScript с обратными вызовами "успех / неудача", что они были асинхронными, но на самом деле это не так. Они асинхронны с точки зрения клиента / браузера, но со стороны сервера выполняется вызов веб-службы, который возвращается после завершения всех других операций, поскольку число подключений ограничено.

Так какой же самый простой способ сделать методы веб-службы асинхронными? Нужно ли преобразовывать веб-службу в веб-службу WCF или можно использовать существующий вызов веб-службы ASP.NET?

И для исторических целей вот то, что я думал, что проблема была первоначально:

Я не смог воспроизвести это локально или на наших серверах тестирования. Тем не менее, я заставил Fiddler имитировать скорость модема, и внезапно я смог скопировать 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

  • Я добавил код очистки Crockenator для утечек памяти в IE (см. 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);
    });
    

    });

Ни одно из моих улучшений не устранило проблему. в моем локальном тестовом сценарии. Есть идеи? Кто-нибудь? Кто-нибудь? Bueller?

Последнее обновление

Спасибо Дэвиду за то, что он указал, что именно состояние сеанса вызывает проблемы в веб-сервисах. "ASP.NET помещает все запросы в один и тот же" сеанс ". Поэтому, если первый запрос блокируется слишком долго, он задержит любые другие запросы в очереди".

В итоге мы постарались минимизировать количество веб-сервисов, используя состояние сеанса, но мы также добавили рекомендуемые настройки Microsoft для количества соединений, см. http://msdn.microsoft.com/en-us/library/ff647786.aspx

1 ответ

Решение

Я думаю, что у вас могут быть проблемы с синхронизацией запросов сеанса. Вы пометили обработчики веб-службы как требующие состояния сеанса?

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" %>
Другие вопросы по тегам