数日前、私は次のような質問をしました。
ほぼ同時に、同じコントローラー アクションで 6 つの jQuery 非同期 Ajax リクエストを発行します。各リクエストが返されるまでに 10 秒かかります。
アクション メソッドへのリクエストをデバッグしてログに記録すると、リクエストがシリアル化され、並列で実行されることはないことがわかります。つまり、log4net ログに次のようなタイムラインが表示されます。
2010-12-13 13:25:06,633 [11164] 情報 - 取得:1156 2010-12-13 13:25:16,634 [11164] 情報 - 戻り値:1156 2010-12-13 13:25:16,770 [7124] 情報 - 取得:1426 2010-12-13 13:25:26,772 [7124] 情報 - 戻り値:1426 2010-12-13 13:25:26,925 [11164] INFO - 取得:1912 2010-12-13 13:25:36,926 [11164] 情報 - 戻り:1912 2010-12-13 13:25:37,096 [9812] 情報 - 取得:1913 2010-12-13 13:25:47,098 [9812] 情報 - 戻り:1913 2010-12-13 13:25:47,283 [7124] 情報 - 取得:2002 2010-12-13 13:25:57,285 [7124] 情報 - 戻る:2002 2010-12-13 13:25:57,424 [11164] 情報 - 取得:1308 2010-12-13 13:26:07,425 [11164] 情報 - 戻り:1308
Firefox のネットワーク タイムラインを見ると、次のようになります。
上記のログ サンプルと Firefox ネットワーク タイムラインは、どちらも同じリクエスト セットに対するものです。
同じページからの同じアクションへのリクエストはシリアル化されますか?Session
同じセッション内のオブジェクトへのシリアル化されたアクセスは認識していますが、セッション データは変更されていません。
クライアント側のコードを単一のリクエスト (最も長く実行されるもの) に削減しましたが、それでもブラウザはブロックされます。つまり、Ajax リクエストが完了したときにのみ、ブラウザはリンクのクリックに応答します。
ここで私が観察したこと (Chrome の開発者ツールで) は、長時間実行される ajax リクエストの実行中にリンクをクリックすると、Failed to load resource
ブラウザが ajax リクエストを強制終了した (または強制終了を試み、待機している?) ことを示すエラーがすぐに報告されることです。
ただし、ブラウザが新しいページにリダイレクトされるまでにはまだ時間がかかります。
Ajax リクエストは本当に非同期なのでしょうか、それとも JavaScript が実際にはシングル スレッドであるため、これは巧妙な策略なのでしょうか?
私のリクエストが機能するまでに時間がかかりすぎているのでしょうか?
この問題は Firefox と IE でも発生します。
また、スクリプトを$.ajax
直接使用して明示的に設定するように変更しましたasync: true
。
私はこれを IIS7.5 で実行していますが、Windows 2008R2 と Windows 7 の両方のバージョンで同じことが行われます。
デバッグビルドとリリースビルドも同じように動作します。
ベストアンサー1
答えは目の前にありました。
ASP.NETセッション状態へのアクセスはセッションごとに排他的であるため、2人の異なるユーザーが同時にリクエストを行った場合、各セッションへのアクセスが同時に許可されます。ただし、同じセッションに対して 2 つの同時リクエスト (同じ SessionID 値を使用) が行われた場合、最初のリクエストはセッション情報への排他的アクセスを取得します。2 番目のリクエストは、最初のリクエストが完了した後にのみ実行されます。
残念なことに、私は数週間前にこの段落をざっと読み、太字の文章のインパクトを十分に理解していませんでした。私はそれを単に「セッション状態へのアクセスはシリアル化されます」そしてそうではない「セッション状態に触れるかどうかに関係なく、すべてのリクエストはシリアル化されます」リクエストが同じセッションから来た場合。
幸いなことに、ASP.NET MVC3 には回避策があり、セッションレス コントローラーを作成できます。Scott Guthrie はここでこれについて説明しています。
MVC3 RC2 をインストールし、プロジェクトをアップグレードしました。問題のコントローラーを装飾すると、[SessionState(SessionStateBehavior.Disabled)]
問題は解決します。
そしてもちろん、典型的な例として、私は数分前に Stack Overflow でこれを見つけました: