24

新しいC#5非同期モデルを使用しようとするAspNetSynchronizationContextと、内部クラス(およびAspNetSynchronizationContextBaseベース)であることに驚きました。したがって、文書化されていません。ただし、ASP.NETコード内で非同期/待機機能を利用する場合の機能を理解することが重要です。あなたの継続が元の発信者と同じになることを保証するの正しいですか?継続が呼び出し元と同じスレッドで実行されることを保証するHttpContext.Currentものではありませんか?

後者の仮定が当てはまらず、元のスレッドを取得した場合、継続して同じスレッドコンテキストを確実に取得できますか?スレッドとスレッドローカルストレージに関連するプリンシパル/カルチャを意味しますか?ASP.NETのローカリゼーションはスレッドの文化に依存しており、私のアプリケーションは.NETの役割のセキュリティモデル(スレッドのプリンシパル)に依存しているため、これは重要です。

4

2 に答える 2

28

継続が元の呼び出し元と同じHttpContext.Currentを取得することを保証するのは正しいですか?継続が呼び出し元と同じスレッドで実行されることを保証するものではありませんか?

はい、HttpContext.Current保持されます。はい、継続は別のスレッドで実行される可能性があります。

スレッドとスレッドローカルストレージに関連するプリンシパル/カルチャを意味しますか?ASP.NETのローカリゼーションはスレッドの文化に依存しており、私のアプリケーションは.NETの役割のセキュリティモデル(スレッドのプリンシパル)に依存しているため、これは重要です。

通常のスレッドローカルストレージは失われます。LogicalCallContext(を使用して流れるExecutionContext)を使用することでこれを軽減できますがasync、変数を直接参照する方が簡単です。

プリンシパルは常に保持されます。そうしないと、セキュリティ上のリスクが発生します。これはで流れExecutionContextます。

文化はで流れると思いますが、 .NET4.5の新しい実装AspNetSynchronizationContextでこれをテストしていません。


私のMSDNの記事がSynchronizationContext役に立ちます。これは公式のドキュメントではありませんが(私はMicrosoftで働いていません)、少なくともそれは何かです。AspNetSynchronizationContextその記事で参照されているものが.NET4.5で呼び出されていることに注意してくださいLegacyAspNetSynchronizationContext

もう1つの優れたリソースは、StephenToubのExecutionContextvs.SynchronizationContextです。

于 2012-09-30T12:28:05.983 に答える
6

ええと、ExecutionContextのキャプチャは常に保証されていますが、同じSynchronizationContextでの実行のキャプチャと実行は、Awaiterに依存します。

最も一般的な待機者(何かを「待機」するときに内部的に呼び出されるGetAwaiter()メソッドによって返されるタイプ)は、Task.GetAwaiter()によって返されるTaskAwaiterです。デフォルトでは、TaskAwaiterは現在のSynchronizationContextをキャプチャし、キャプチャされたSynchronizationContextで継続デリゲートを実行します。つまり、メソッドの残りの部分でHttpContext.Currentを使用できるようになり、継続として実行されることを気にする必要はありません。したがって、このコードは期待どおりに機能します(「B」を記述した部分は、最初の行と同じ同期コンテキストで実行されます)。

HttpContext.Current.Response.Write("A");
await Task.Delay(1000);
HttpContext.Current.Response.Write("B")

メソッドを使用してこの動作を変更できます。これによりTask.ConfigureAwait(false)、ウェイターはメソッドの残りの部分を元のSynchronizationContextにマーシャリングしないように指示されます。

もちろん、呼び出している非同期メソッドでTask.RunまたはTask.Factory.StartNewを使用する場合は、SynchronizationContextを再度キャプチャするのはあなたの責任です。

幸運を祈ります。

于 2012-09-30T09:28:33.633 に答える