Этот комментарий от Стивен Клири говорит следующее:
AspNetSynchronizationContext
- самая странная реализация. Он рассматриваетPost
как синхронный, а не асинхронный, а использует блокировку для выполнения своих делегатов по одному за раз.
Аналогично, статья, которую он написал в контекстах синхронизации и связанная с этим комментарием, предлагает:
Концептуально контекст AspNetSynchronizationContext является сложным. Во время жизни асинхронной страницы контекст начинается только с одного потока из пула потоков ASP.NET. После запуска асинхронных запросов контекст не содержит потоков. По завершении асинхронных запросов потоки потоков, выполняющие свои процедуры завершения, входят в контекст. Это могут быть те же потоки, которые инициировали запросы, но, скорее всего, были бы потоками, которые были бы свободными в момент завершения операций.
Если несколько операций завершаются сразу для одного и того же приложения, AspNetSynchronizationContext гарантирует, что они будут выполнять одно за раз. Они могут выполняться в любом потоке, но этот поток будет иметь личность и культуру исходной страницы.
Копающий рефлектор, похоже, подтверждает это, поскольку он блокирует HttpApplication
при вызове любого обратного вызова.
Блокировка объекта приложения кажется пугающим. Итак, мой первый вопрос: означает ли это, что сегодня все асинхронные доработки для всего приложения выполняются по одному за раз, даже те, которые возникли из отдельных запросов на отдельные потоки с отдельными HttpContexts? Разве это не было бы огромным узким местом для любых приложений, которые на 100% используют асинхронные страницы (или асинхронные контроллеры в MVC)? Если нет, почему бы и нет? Что мне не хватает?
Кроме того, в .NET 4.5 он выглядит как новый AspNetSynchronizationContext
, а старый переименован LegacyAspNetSynchronizationContext
и используется только в том случае, если новый параметр приложения UseTaskFriendlySynchronizationContext
не установлен. Итак, вопрос № 2: изменилось ли это изменение в новой реализации? В противном случае я предполагаю, что с помощью нового асинхронного/ждущего завершения маршалинга завершения через контекст синхронизации этот вид узкого места будет замечен гораздо чаще в будущем.
Ответ на этот пост форума (связанный с SO answer здесь) предполагает, что что-то принципиально изменилось здесь, но я хочу четко понимать, что это такое и какие улучшения поведения улучшились, поскольку у нас есть приложение .NET 4 MVC 3, которое представляет собой почти 100% асинхронные действия, вызывающие вызовы веб-сервисов.