AddOnEndRequestAsync
HttpApplication 非同期イベント (たとえば、使用して登録されたイベントやフレンド)はどの程度非同期ですか? IIS は、特定のイベントに対して発生したすべての非同期イベントが完了するのを待ってから、次のイベントに移りますか?
1 に答える
統合されたパイプライン モードで実行するときの正確な動作は明確ではありませんが、統合されていない場合に何が見えるかはわかります。セマンティクスは同じままである必要があります。
簡単に言うと、各イベント ハンドラーは、同期か非同期かにかかわらず、順番に起動され、前のイベント ハンドラーが完了するまで次のイベントは起動されないということです。
これは、ソース コードから追跡できます。
リクエストが到着し、キューに格納されます。通常、 がHttpRuntime
リクエストをデキューするとき、HttpApplication
そのメソッドを呼び出してを引数としてInitInternal
渡し、リクエストの を初期化します。HttpContext
HttpApplication.InitInternal
HttpApplication.ApplicationStepManager
非統合モードの場合の新しいクラスを初期化します。BuildSteps
次に、それがメソッドを呼び出していることがわかります。これにより、ArrayList
ステップを格納する が作成され、すべてのステップが構築および格納されます。具体的には、これらの手順はIExecuteStep
インターフェイスの実装です。最終的に、すべてのステップが追加されると、リストを配列にコピーし、後で使用できるようにメンバー var に保存することでリストが完成し_execSteps
ます。
ステップにはいくつかのソースがありますが、最もよく使用されるのHttpApplication.CreateEventExecutionSteps
は、イベント タイプ (要求の開始、承認など) と、そのイベントのステップを追加するためのステップ配列を受け取る ですCreateEventExecutionSteps
。それぞれ、およびテーブルIExecuteStep
から、認識している for each async および sync ハンドラーを追加していることがわかります。インターフェイス自体は、基本的にメソッドとフラグで構成されます。AsyncEvents
Events
IExecuteStep
Execute
CompletedSynchronously
ここで、一時停止して、前述のような Add メソッドの 1 つを振り返るとAddOnEndRequestAsync
、非同期ハンドラーに関する情報がテーブルに追加されていることがわかりAsyncEvents
ます。 CreateEventExecutionSteps
次に、このテーブルをウォークスルーし、AsyncEventExecutionStep
追加された各ハンドラに対して が構築されます。
リクエストフローに戻ります。HttpRuntime
がリクエストに対して を初期化した後、そのメソッドをHttpApplication
呼び出してを起動します。BeginProcessRequest
ResumeSteps
ResumeSteps
ステップがどのように使用され、非同期の場合の待機戦略が何であるかを確認できる重要なものです。_currentStepIndex
実行ステップの配列に を維持していることがわかります。Execute
最終的に、配列から次のステップを取得し、そのメソッドを呼び出すことがわかります。ステップがその実行CompletedSynchronously
を報告すると、ループして再び実行されます。そうでない場合は、メソッドを完了させ、非同期の深淵に入ります。
この非同期ケースで何が起こるかを確認するにはAsyncEventExecutionStep
、非同期ハンドラー用に作成された実装を確認する必要があります。そのExecute
実装では、開始ハンドラーを起動し、完了コールバックを渡すことがわかります。コンストラクターでは、このコールバックが最終的に呼び出すメソッドに初期化されていることがわかります...HttpApplication.ResumeSteps
再び!
そのため、アレイがオーバーランするまでステップ、同期または非同期を実行し続け、その時点でリクエスト処理を「終了」します。
要点は、追加したイベント ハンドラーに変換されるステップが 1 つずつ実行され、同期か非同期かに関係なく、現在のステップが完了するまで次のステップが実行されないことがはっきりとわかります。あなたの質問は、イベントがこのように 1 つずつ処理されるかどうかでしたが、実際には、各イベント ハンドラーがこのように処理されるため、さらにきめ細かく処理されるため、それぞれが HttpContext への同期アクセスを取得し、なしで動作できます。彼らがまだパイプラインの「正しい段階」にあるかどうかを心配しています。
明らかに、そのソース コードには他にも詳細がありますが、やだやだですが、これが要点です。