2013-11-01 2 views
4

Я разбирался в этой проблеме весь день и надеюсь, что кто-то может помочь определить мою проблему. Я создал функцию асинхронного выполнения обратного вызова в моем приложении с помощью ajax. Когда я удаляю функциональность в тестовое приложение, я получаю желаемые результаты. Смотрите изображение ниже:Asp.Net MVC и ajax async callback order order

желаемая функциональность enter image description here

Когда я связать функциональность в моей одной странице приложения, используя один и тот же код, я получаю своего рода блокирующий вопрос, где все запросы откликнулись только после последней задачи завершено. В тестовом приложении все запросы отвечают по порядку. Сервер сообщает («ожидающее») состояние для всех запросов до тех пор, пока не будет завершен метод контроллера. Может ли кто-нибудь дать мне подсказку о том, что может вызвать изменение в поведении?

Не Желаемая enter image description here

Желаемая Скрипач Request/Response

GET http://localhost:12028/task/status?_=1383333945335 HTTP/1.1 
X-ProgressBar-TaskId: 892183768 
Accept: */* 
X-Requested-With: XMLHttpRequest 
Referer: http://localhost:12028/ 
Accept-Language: en-US 
Accept-Encoding: gzip, deflate 
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0) 
Connection: Keep-Alive 
DNT: 1 
Host: localhost:12028 

HTTP/1.1 200 OK 
Cache-Control: private 
Content-Type: text/html; charset=utf-8 
Vary: Accept-Encoding 
Server: Microsoft-IIS/8.0 
X-AspNetMvc-Version: 3.0 
X-AspNet-Version: 4.0.30319 
X-SourceFiles: =?UTF-8?B?QzpcUHJvamVjdHNcVEVNUFxQcm9ncmVzc0Jhclx0YXNrXHN0YXR1cw==?= 
X-Powered-By: ASP.NET 
Date: Fri, 01 Nov 2013 21:39:08 GMT 
Content-Length: 25 

Iteration completed... 

Не Желаемая Скрипач Request/Response

GET http://localhost:60171/_Test/status?_=1383341766884 HTTP/1.1 
X-ProgressBar-TaskId: 838217998 
Accept: */* 
X-Requested-With: XMLHttpRequest 
Referer: http://localhost:60171/Report/Index 
Accept-Language: en-US 
Accept-Encoding: gzip, deflate 
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0) 
Connection: Keep-Alive 
DNT: 1 
Host: localhost:60171 
Pragma: no-cache 
Cookie: ASP.NET_SessionId=rjli2jb0wyjrgxjqjsicdhdi; AspxAutoDetectCookieSupport=1; TTREPORTS_1_0=CC2A501EF499F9F...; __RequestVerificationToken=6klOoK6lSXR51zCVaDNhuaF6Blual0l8_JH1QTW9W6L-3LroNbyi6WvN6qiqv-PjqpCy7oEmNnAd9s0UONASmBQhUu8aechFYq7EXKzu7WSybObivq46djrE1lvkm6hNXgeLNLYmV0ORmGJeLWDyvA2 


HTTP/1.1 200 OK 
Cache-Control: private 
Content-Type: text/html; charset=utf-8 
Vary: Accept-Encoding 
Server: Microsoft-IIS/8.0 
X-AspNetMvc-Version: 4.0 
X-AspNet-Version: 4.0.30319 
X-SourceFiles: =?UTF-8?B?QzpcUHJvamVjdHNcSUxlYXJuLlJlcG9ydHMuV2ViXHRydW5rXElMZWFybi5SZXBvcnRzLldlYlxfVGVzdFxzdGF0dXM=?= 
X-Powered-By: ASP.NET 
Date: Fri, 01 Nov 2013 21:37:48 GMT 
Content-Length: 25 

Iteration completed... 

Единственное отличие в двух заголовках запросов, кроме токенов auth, - «Pragma: no-cache» в запросе и версия asp.net в ответе.

Благодаря

Update - Код размещен (я, вероятно, нужно указать этот код возник из article Дино Эспозито)

var ilProgressWorker = function() { 
    var that = {}; 
    that._xhr = null; 
    that._taskId = 0; 
    that._timerId = 0; 
    that._progressUrl = ""; 
    that._abortUrl = ""; 
    that._interval = 500; 
    that._userDefinedProgressCallback = null; 
    that._taskCompletedCallback = null; 
    that._taskAbortedCallback = null; 
    that.createTaskId = function() { 
     var _minNumber = 100, 
      _maxNumber = 1000000000; 
     return _minNumber + Math.floor(Math.random() * _maxNumber); 
    }; 

    // Set progress callback 
    that.callback = function (userCallback, completedCallback, abortedCallback) { 
     that._userDefinedProgressCallback = userCallback; 
     that._taskCompletedCallback = completedCallback; 
     that._taskAbortedCallback = abortedCallback; 
     return this; 
    }; 

    // Set frequency of refresh 
    that.setInterval = function (interval) { 
     that._interval = interval; 
     return this; 
    }; 

    // Abort the operation 
    that.abort = function() { 
     //  if (_xhr !== null) 
     //   _xhr.abort(); 
     if (that._abortUrl != null && that._abortUrl != "") { 
      $.ajax({ 
       url: that._abortUrl, 
       cache: false, 
       headers: { 'X-ProgressBar-TaskId': that._taskId } 
      }); 
     } 
    }; 

    // INTERNAL FUNCTION 
    that._internalProgressCallback = function() { 
     that._timerId = window.setTimeout(that._internalProgressCallback, that._interval); 
     $.ajax({ 
      url: that._progressUrl, 
      cache: false, 
      headers: { 'X-ProgressBar-TaskId': that._taskId }, 
      success: function (status) { 
       if (that._userDefinedProgressCallback != null) 
        that._userDefinedProgressCallback(status); 
      }, 
      complete: function (data) { 
       var i=0; 
      }, 
     }); 
    }; 

    // Invoke the URL and monitor its progress 
    that.start = function (url, progressUrl, abortUrl) { 
     that._taskId = that.createTaskId(); 
     that._progressUrl = progressUrl; 
     that._abortUrl = abortUrl; 

     // Place the Ajax call 
     _xhr = $.ajax({ 
      url: url, 
      cache: false, 
      headers: { 'X-ProgressBar-TaskId': that._taskId }, 
      complete: function() { 
       if (_xhr.status != 0) return; 
       if (that._taskAbortedCallback != null) 
        that._taskAbortedCallback(); 
       that.end(); 
      }, 
      success: function (data) { 
       if (that._taskCompletedCallback != null) 
        that._taskCompletedCallback(data); 
       that.end(); 
      } 
     }); 

     // Start the progress callback (if any) 
     if (that._userDefinedProgressCallback == null || that._progressUrl === "") 
      return this; 
     that._timerId = window.setTimeout(that._internalProgressCallback, that._interval); 
    }; 

    // Finalize the task 
    that.end = function() { 
     that._taskId = 0; 
     window.clearTimeout(that._timerId); 
    } 

    return that; 
}; 

Update 1 - Большое спасибо John Saunders. Я смог найти статью this, в которой объясняется, что Джон подразумевал в своем комментарии о сериализованном доступе.

«» Он блокирует параллельное выполнение и заставляет параллельные запросы выполняться один за другим, поскольку доступ к состоянию сеанса ASP.NET является эксклюзивным за сеанс "

+0

Можете ли вы разместить код? –

+0

Держу пари, что код, вызываемый вашим AJAX, использует состояние сеанса. ASP.NET будет сериализовать доступ к состоянию сеанса. –

+0

Большое спасибо, Джон! Когда я добавил аутентификацию и состояние сеанса в тестовое клиентское приложение, я смог заметить то же поведение, что и в моем приложении. –

ответ

1

Я нашел исправление наконец. Состояние сеанса можно контролировать на уровне контроллера и/или контроллера. Поскольку авторизация проверяется на более высоком уровне, нет необходимости использовать сеанс в том, что я делаю. Я просто отключил его для единицы работы.

[SessionState(SessionStateBehavior.Disabled)] 
public class _TestController : ProgressWorkerController