ASP.NET SessionState解惑
1980 ワード
ふみだめ
近日1つのASPに対してNET WEBFORMプロジェクトのチューニング中、ページPOSTBACKイベントがシリアル処理されていることに偶然気づき、異なるページのリクエストもシリアル処理されている(1ページのロードが完了してから、2ページ目のロードが開始される).しかし、サイトは要求を同時に処理しているのに、その時は理解できず、コードを繰り返して長い間調べて、業務の枠組みの中でどこがリソースをロックしているのかを探していました.各種のブレークポイント、デバッグ、ログをすべて使用しても、原因が見つかりません.よく考えてみましたASP.NETはシリアル処理ではないに違いないが、あるSessionの中でASP.NETはそのシリアル処理要求に対して?
雷を落とす
プロジェクトにページを追加するには、最も簡単なイベントコードしか追加できません.
log.Info("start");
System.Threading.Thread.Sleep(5000);
log.Info("end");
ブラウザで2つのラベルページを開いて同時にページにアクセスし、結果要求時に並列に処理します.
16:24:44[9]start
16:24:45[10]start
16:24:49[9]end
16:24:50[10]end
次に、ログインページにアクセスしてから、前回の動作を繰り返し、シリアル処理を要求します!
16:26:11[9]start
16:26:16[9]end
16:26:16[10]start
16:26:21[10]end
2つのブラウザに切り替え,それぞれログインしてそのページにアクセスし,要求を並列に処理する.ここから確認するのはSESSIONの問題に違いない!
GOOGLEは検索して、原因と解決策を見つけました:
The session state module implements a locking mechanism and queues the access to state values. A page that has session-state write access will hold a writer lock on the session until the request finishes. A page gains write access to the session state by setting the EnableSessionState attribute on the @Page directive to True. A page that has session-state read access -- for example, when the EnableSessionState attribute is set to ReadOnly -- will hold a reader lock on the session until the request finishes.
SessionStateModuleソース
従来、SessionStateModuleモジュールは書き込みロックを実現し、キュー処理を行うため、同じSESSIONでのすべてのリクエストがシリアルで実行されます.
ソリューションも簡単で、ページにEnableSessionState=「ReadOnly」コマンドを追加すればよい.もちろん、このコマンドを追加すると、このページではSESSION値を変更することはできません.
派生
GOOGLEの过程の中で、発见します.NET MVCにも同様にこの問題があり,その解決策はcontroller上に特性を追加することである[SessionState(SessionStateBehavior.ReadOnly)]
手当たり次第に実験して、以上の特性を加えない場合、SESSIONがある場合、SESSIONとのリクエストはシリアル処理されます.SessionStateBehaviorを追加ReadOnly後の異なるactionではリクエストは並列に処理されますが、同じactionでもシリアル処理されます.Taskでも、シリアル実行の魔の手から逃れられない.