3

ASP.NET アプリは、同じセッションで複数の Ajax 要求を並行して送信します。HttpSessionStateまた、これらのリクエストの一部で読み取り/書き込みを行います。私が望むのは、パフォーマンス上の理由から、すべての同時リクエストを並行して実行することです。私が得たのは、それらが ASP.NET によってシリアル化されているということです。の構成を試してみましenableSessionState="ReadOnly"たが、フォーム認証が機能しなくなります。

1 つのセッションでセッション状態と同時実行の両方を取得する方法はありますか? カスタムSessionStateまたはを使用する必要がありますかProvider? これのサンプルはありますか?

PS SessionState にアクセスするときのスレッドの安全性については心配していません。プログラムで実行できます。

4

1 に答える 1

2

MSDN から (リンク):

ただし、同じセッションに対して (同じ SessionID 値を使用して) 2 つの同時要求が行われた場合、最初の要求はセッション情報への排他的アクセスを取得します。2 番目の要求は、最初の要求が終了した後にのみ実行されます。

したがって、少なくともセッションへの書き込みアクセスを必要とする AJAX 呼び出しについては、デフォルトのプロバイダーではうまくいきません。

カスタム プロバイダーを使用してこれを回避できるかどうかはわかりません。

でCookie をブロックすることにより、セッションへのアクセスを必要としない AJAX 呼び出しの並列実行を実現できます。この質問に対する私の回答を参照してください。ASP.NET_SessionIdHttpModule

編集:この回答をより自立させるために、少し修正したバージョンと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がクライアントの既存の Cookie を破棄するのを防ぐために、作成後すぐに破棄します。

最終的に、モジュールによって「インターセプト」された各リクエストは、セッションがないかのように実行されます。

于 2012-08-29T11:48:33.433 に答える