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でも、シリアル実行の魔の手から逃れられない.