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%非同期アクションメソッド。