ConfigureAwait (false) актуально в ASP.NET Core?

106

Я наткнулся на проблему ( https://github.com/HTBox/allReady/issues/1313 ) на GitHub, где они обсуждали удаление ConfigureAwait(false)кода, утверждая, что в ASP.NET Core

вызов ConfigureAwait(false)является избыточным и ничего не делает

Лучшее, что я смог найти здесь, - это «примечание» в ответе (от Стивена Клири, https://stackoverflow.com/a/40220190/2805831 ), в котором говорится, что

ASP.NET Core больше не имеет «контекста»

Итак, ConfigureAwait(false)действительно ли это не нужно в ASP.NET Core (даже при использовании полной .Net Framework)? Есть ли реальный прирост производительности в некоторых случаях или разница в результате / семантике?

РЕДАКТИРОВАТЬ: В этом аспекте все по-другому, если я размещаю его как консольное приложение или в IIS?

Педро Лоренц
источник
2
Это зависит от того, где вы собирались его использовать. Если вы хотите использовать его непосредственно в своем приложении ASP.NET Core, тогда нет, вам не нужно его называть (вам не нужно было вызывать его в устаревших версиях ASP.NET или iirc). Но если вы пишете библиотеку, вы всегда должны использовать ее ConfigureAwait(false), поскольку библиотека может использоваться различными приложениями (ASP.NET Core, WPF, UWP, Console и т. Д.)
Tseng
1
ASP.NET Core по умолчанию работает как консольное приложение, а консольные приложения AFAIK не имеют SynchronizationContext, так что да, это звучит разумно для приложения ASP.NET Core по умолчанию, даже с полной Framework.
Джо Уайт
@JoeWhite Хорошо, отредактировал вопрос. Разве это не так, если мое приложение ASP.NET Core находится в IIS?
Педро Лоренц
3
Приложение ASP.NET Core, работающее в IIS, по-прежнему работает как консольное приложение - единственное отличие состоит в том, что IIS запускает и закрывает экземпляры вашего приложения (точно так же, как он управлял бы экземплярами рабочего процесса ASP.NET в классический ASP.NET). Это не повлияет на поведение, связанное с потоками, внутри вашего приложения ASP.NET. (Единственная причина , я указал «по умолчанию» является то , что вы могли бы, например, хост ASP.NET ядро внутри приложения с графическим интерфейсом, и в этом случае вы бы должны думать о контексте синхронизации.)
Joe White
Примечание. ConfigureAwait(false)Хотя это и актуально для классической версии ASP.NET, в этом нет необходимости . Это компромисс: он как бы смягчает некоторые взаимоблокировки синхронизации по асинхронности (которые в любом случае являются недостатками дизайна - они не существуют, если кто-то не делает что-то глупое) и иногда дает повышение производительности ~ микросекунды, не перезагружая контекст. Ценой невозможности зависеть от контекста и ConfigureAwaitпрохождения всего кода. stackoverflow.com/questions/28221508/…
Dax Fohl

Ответы:

113

ConfigureAwaitвлияет только на код, выполняющийся в контексте, SynchronizationContextкоторого нет в ASP.NET Core (в ASP.NET «Legacy» есть).

Код общего назначения должен по-прежнему использовать его, потому что он может работать с расширением SynchronizationContext.

Контекст синхронизации ASP.NET Core

Пауло Моргадо
источник
19
Просто хочу внести небольшое пояснение: ASP.NET в неосновной среде имеет контекст синхронизации, а ядро ​​ASP.NET - нет.
Скотт Чемберлен
@Morgado, это правда, даже если приложение размещено в IIS?
Педро Лоренц
7
Приложение ASP.NET Core не размещается в IIS. IIS действует как обратный прокси.
Пауло Моргадо
2
Я обновил ответ недавним сообщением Стивена Клири. Но да, ASP.NET Core - это ASP.NET Core.
Пауло Моргадо
14
@NamNgo. Обратите внимание, что это старый пост, но Стивен Клири разъясняет это в одном из вопросов к посту, на который Пауло указал выше. «Это структура (ASP.NET Core в отличие от ASP.NET Classic), которая определяет SynchronizationContext, а не среду выполнения (.NET Core в отличие от .NET 4.6.2)»
Гэвин Сазерленд
14

Как насчет этого?

В настоящий момент (февраль 2020 г.) разработчики в блоге MS рекомендуют использовать ConfigureAwait (false) для повышения производительности и предотвращения взаимоблокировок. https://devblogs.microsoft.com/dotnet/configureawait-faq/

Я слышал, что ConfigureAwait (false) больше не требуется в .NET Core. Правда? Ложь. Это необходимо при работе в .NET Core по тем же причинам, что и при работе в .NET Framework. В этом отношении ничего не изменилось.

Альфред Северо
источник
Если какой-либо пользовательский код (или другой код библиотеки, который использует ваше приложение) устанавливает настраиваемый контекст и вызывает ваш код или вызывает ваш код в Задаче, запланированной для настраиваемого TaskScheduler, то даже в ASP.NET Core ваши ожидания могут увидеть не- контекст или планировщик по умолчанию, из-за которых вы захотите использовать ConfigureAwait (false). Конечно, в таких ситуациях, если вы избегаете синхронной блокировки (чего вам следует избегать в веб-приложениях в любом случае) и если вы не возражаете против небольших накладных расходов на производительность в таких ограниченных случаях, вы, вероятно, можете обойтись без использования ConfigureAwait (false) .
Алиссон
2
В соответствии с этим я бы сказал, что в большинстве случаев это не нужно. Если вы не используете настраиваемый контекст синхронизации или библиотеку, которая это делает.
Алиссон,