13

Stephen Clearyによるこのコメントは、次のように述べています。

AspNetSynchronizationContext最も奇妙な実装です。Post非同期ではなく同期として扱い、ロックを使用してデリゲートを一度に1つずつ実行します。

同様に、彼が同期コンテキストについて書き、そのコメントにリンクしている記事は、次のことを示唆しています。

概念的には、AspNetSynchronizationContextのコンテキストは複雑です。非同期ページの存続期間中、コンテキストはASP.NETスレッドプールからの1つのスレッドから始まります。非同期リクエストが開始された後、コンテキストにはスレッドが含まれません。非同期要求が完了すると、完了ルーチンを実行しているスレッドプールスレッドがコンテキストに入ります。これらは、要求を開始したスレッドと同じである可能性がありますが、操作の完了時にたまたま空いているスレッドである可能性が高くなります。

同じアプリケーションに対して複数の操作が同時に完了する場合、AspNetSynchronizationContextは、それらが一度に1つずつ実行されることを保証します。これらはどのスレッドでも実行できますが、そのスレッドには元のページのIDとカルチャがあります。

リフレクターを掘り下げるとHttpApplication、コールバックの呼び出し中にロックがかかるため、これを検証するようです。

アプリオブジェクトをロックするのは恐ろしいことのようです。だから私の最初の質問:それは、今日、アプリ全体のすべての非同期完了が一度に1つずつ実行されることを意味しますか?これは、非同期ページ(またはMVCの非同期コントローラー)を100%使用するアプリにとって大きなボトルネックではないでしょうか?そうでない場合は、なぜですか?私は何が欠けていますか?

また、.NET 4.5では、新しいものがあるように見えますAspNetSynchronizationContext。古いものは名前が変更LegacyAspNetSynchronizationContextされ、新しいアプリ設定UseTaskFriendlySynchronizationContextが設定されていない場合にのみ使用されます。質問#2:新しい実装はこの動作を変更しますか?そうでなければ、同期コンテキストを介した新しいasync / awaitサポートのマーシャリング完了により、この種のボトルネックは今後さらに頻繁に認識されると思います。

このフォーラム投稿への回答(ここのSO回答からリンクされています)は、ここで根本的に何かが変わったことを示唆していますが、.NET 4 MVC 3アプリがあるので、それが何であり、どのような動作が改善されたかを明確にしたいと思いますWebサービス呼び出しを行う100%非同期アクションメソッド。

4

1 に答える 1

12

最初の質問にお答えします。あなたの仮定では、別々のASP.NET要求が異なるHttpApplicationオブジェクトによって処理されるという事実を考慮していませんでした。HttpApplicationオブジェクトはプールに保存されます。ページをリクエストすると、アプリケーションオブジェクトがプールから取得され、完了するまでリクエストに属します。だから、あなたの質問に対する私の答え:

アプリ全体のすべての非同期完了は、一度に1つずつ実行されます。これは、個別のHttpContextを持つ個別のスレッドでの個別のリクエストから発生したものも含まれます。

は:いいえ、彼らはしません

個別のリクエストは個別のHttpApplicationオブジェクトによって処理され、ロックされたHttpApplicationは単一のリクエストにのみ影響します。同期コンテキストは、開発者が共有(要求の範囲内)リソースへのアクセスを同期するのに役立つ強力なものです。これが、すべてのコールバックがロックされた状態で実行される理由です。同期コンテキストは、イベントベースの同期パターンの中心です。

于 2012-07-31T06:02:27.913 に答える