2012-08-29 5 views
3

Наше приложение ASP.NET отправляет несколько запросов Ajax параллельно в одном сеансе. Мы также читаем/пишем до HttpSessionState во время некоторых из этих запросов. Я хочу, чтобы все параллельные запросы выполнялись параллельно по соображениям производительности. Я получаю, что они сериализованы ASP.NET. Я экспериментировал с настройкой enableSessionState="ReadOnly", но это нарушает нашу проверку подлинности с помощью форм.Поставщики состояния сеанса ASP.NET

Есть ли способ получить как состояние сеанса, так и параллелизм в одном сеансе? Нужно ли использовать пользовательские SessionState или Provider? Какие-нибудь образцы этого там?

PS Я не беспокоюсь о безопасности потоков при доступе к SessionState - я могу сделать это программно.

ответ

2

Из MSDN (link):

Однако, если два одновременных запросов сделаны на той же сессии (с использованием того же значения SessionID), то первый запрос получает эксклюзивный доступ к информации о сеансе связи. Второй запрос выполняется только после завершения первого запроса.

Так что, по крайней мере, для тех вызовов AJAX, которым требуется доступ на запись к сеансу, вам не повезло с поставщиками по умолчанию.

Не уверен, можете ли вы обойти это с помощью специального поставщика.

Вы может достичь parallell выполнения для этих вызовов AJAX, которые не нуждаются в доступе к сессии, блокируя ASP.NET_SessionId печенья в HttpModule. См. Мой answer к этому question.

Edit: Для того, чтобы сделать этот ответ более самонадеянным, я добавляю немного измененную версию HttpModule и немного обсуждения (далее вниз). Вот код модуля, который можно использовать для предотвращения состояния сеанса из сериализации вашего Ajax звонков:

using System; 
using System.Web; 

namespace TestModule 
{ 
    public class TestPreventCookie : IHttpModule 
    { 
     public void Dispose() 
     { 
     } 
     public void Init(HttpApplication application) 
     { 
      application.BeginRequest += 
       (new EventHandler(this.Application_BeginRequest)); 
      application.PostAcquireRequestState += 
       (new EventHandler(this.Application_PostAcquireRequestState)); 

     } 
     private void Application_BeginRequest(Object source, EventArgs e) 
     { 
      //prevent session cookie from reaching the service 
      HttpApplication application = (HttpApplication)source; 
      HttpContext context = application.Context; 
      if (BlockCookie(context)) 
      { 
       context.Request.Cookies.Remove("ASP.NET_SessionId"); 
      } 
     } 
     private void Application_PostAcquireRequestState(Object source, EventArgs e) 
     { 
      HttpApplication application = (HttpApplication)source; 
      HttpContext context = application.Context; 
      if (BlockCookie(context)) 
      { 
       var s = context.Session; 
       if (s != null) 
        s.Abandon(); 
      } 
     } 
     private bool BlockCookie(HttpContext context) 
     { 
      // put code here that determines if the session cookie should be blocked 
      // this could be based on the path of the current request for instance 
      // only block the cookie when you *know* that access to the Session is not needed 
     } 
    } 
} 

Идея этого модуля состоит в том, что с помощью некоторых критериев, основанных на требованиях к проекту, мы убираем ASP.NET_SessionId печенья из текущего контекста (заметьте, мы не истекаем его на клиенте).

Это означает, что далее в конвейере запроса сервер создаст новый сеанс. Чтобы этот недавно созданный сеанс не уничтожал существующий файл cookie ASP.NET_SessionId на клиенте, мы оставляем его сразу после его создания.

Конечным результатом является то, что каждый запрос, «перехваченный» модулем, будет выполняться так, как если бы у него не было сеанса.

Смежные вопросы