Подтвердить что ты не робот

JQuery $.ajax вызывает синхронное выполнение вместо одновременного вызова вызовов службы WCF

У меня есть веб-приложение, содержащее страницу с формой, на которой есть сотни полей. Изменение любого из полей вызывает вызов jQuery $.ajax на сервер, чтобы определить, нужно ли добавлять другие формы в форму на основе нового значения. Другими словами, он проверяет, нужно ли добавлять какие-либо зависимые поля в форму при изменении одного поля.

В этом процессе есть немного сложности, и в результате иногда эти проверки могут занять несколько секунд.

Проблема в том, что если одно поле находится в середине своего вызова $.ajax, и я пытаюсь изменить другое поле, ожидая завершения первого, пользовательский интерфейс блокируется, и я ничего не могу сделать на до завершения первого вызова. Он, как пользовательский интерфейс, может обрабатывать только один вызов $.ajax за раз. Здесь копия вызова $.ajax:

$.ajax({
        type: "POST",
        async: true,
        url: serviceUrl,
        data: JSON.stringify(data),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        processdata: true,
        success: serviceSuccess,
        error: serviceFailed
    });

Обратный вызов serviceSuccess имеет много сложного кода для обновления пользовательского интерфейса, но я удалил ВСЕ код внутри него, и проблема все еще возникает. Я полагал, что это не связано с обратным вызовом, поскольку, похоже, это происходит до завершения вызова, но, чтобы быть уверенным, я дал ему шанс.

Кто-нибудь слышал о чем-то подобном ранее с jQuery $.ajax?

EDIT: Я заметил, что размер ответа, возвращаемого из вызова $.ajax, составляет около 130 тыс.

Изменить 2:. Запросы $.ajax вызывают вызовы для службы WCF. Определение класса теперь выглядит следующим образом:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ReviewDataService : IReviewDataService, IReadOnlySessionState 

РЕШЕНИЕ: Итак, Джейсон определенно указал мне в правильном направлении. Моя проблема была, по сути, связана с блокировкой сеанса ASP.NET. Чтобы обойти это, мне пришлось исключить использование сеанса из любой точки стека вызовов при вызовах, которые возникли из моей службы WCF. Кроме того, я установил AspNetCompatibilityRequirementsMode в AspNetCompatibilityRequirementsMode.NotAllowed, и я установил aspNetCompatibilityEnabled = "false" в элементе serviceHostingEnvironment в web.config.

Это заставило WCF выкидывать ошибки, когда была предпринята попытка доступа к сессиям, и я juts реорганизовал каждый из этих экземпляров, чтобы они не полагались на сеанс. После этого мои вызовы WCF запускались одновременно, а не синхронно.

4b9b3361

Ответ 1

Если вы используете ASP.NET, они используют блокировки чтения/записи для объекта Session. Это делает запрос AJAX серийным.

В ASP.NET у вас могут быть IHttpHandlers, которые реализуют IReadOnlySessionState, которые не будут размещать блокировку чтения/записи на сеансе. Не уверен, какая среда вы используете.

Изменить 1

В этом сообщении показано, что службы WCF не позволяют вам разблокировать сеанс:

Как заставить IIS размещать WCF или ASMX [webservice] для использования объекта сеанса readonly?

Изменить 2

Настройка IHttpHandler, который не будет блокировать объект Session.

Web.config

<configuration>
    <connectionStrings>
    </connectionStrings>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <add name="Access-Control-Allow-Origin" value="*" />
            </customHeaders>
        </httpProtocol>
        <modules runAllManagedModulesForAllRequests="true" />
        <handlers>
            <add name="MyProvider" path="MyProvider.aspx" verb="*" type="MyNamespace.MyProvider" resourceType="Unspecified" />
        </handlers>
    </system.webServer>
</configuration>

MyProvider.cs

using System;
using System.Web;
using System.Web.SessionState;

namespace MyNamespace
{
    public class MyProvider : IHttpHandler, IReadOnlySessionState
    {
        public bool IsReusable
        {
            get { return true; }
        }

        public void ProcessRequest(HttpContext context)
        {
        }
    }
}

Если вы хотите создать поставщика, который получает и возвращает объекты JSON, вы можете создавать классы для запроса и ответа, а затем ваш обработчик может быть настроен следующим образом:

MyProvider.cs(обработка объектов JSON)

using System;
using System.Runtime.Serialization.Json;
using System.Web;
using System.Web.SessionState;

namespace TestWebsite
{
    public class MyProvider : IHttpHandler, IReadOnlySessionState
    {
        public bool IsReusable
        {
            get { return true; }
        }

        public void ProcessRequest(HttpContext context)
        {
            var response = new Json.Response();
            try
            {
                var requestSerializer = new DataContractJsonSerializer(typeof(Json.Request));
                var request = (Json.Request)requestSerializer.ReadObject(context.Request.InputStream);

                // ...
            }
            catch (Exception ex)
            {
                response.Error = ex.ToString();
            }

            try
            {
                var responseSerializer = new DataContractJsonSerializer(typeof(Json.Response));
                context.Response.ContentType = "application/json";
                responseSerializer.WriteObject(context.Response.OutputStream, response);
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}