ConfigureAwait (false), що стосується ASP.NET Core?


100

Я наткнувся на проблему ( 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)? Чи має це реальний виграш у продуктивності в деяких випадках або різниця в результаті / семантиці?

EDIT: Чи відрізняється в цьому аспекті, якщо я розміщую його як консольний додаток або в IIS?


2
Це залежить від того, де ви планували його використовувати. Якщо ви хотіли використовувати його безпосередньо у своїй програмі ASP.NET Core, тоді ні, вам не потрібно його викликати (вам не доводилося викликати його у застарілій версії ASP.NET, ані iirc). Але якщо ви пишете бібліотеку, то вам завжди слід користуватися ConfigureAwait(false), оскільки бібліотека може використовуватися різними програмами (ASP.NET Core, WPF, UWP, консоль тощо)
Ценг

1
ASP.NET Core за замовчуванням працює як консольна програма, а консольні програми AFAIK не мають SynchronizationContext, тому так, це звучить розумно для стандартної програми ASP.NET Core, навіть з повною структурою.
Joe White

@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/…
Дакс Фол

Відповіді:


105

ConfigureAwaitвпливає лише на код, який працює в контексті, SynchronizationContextякого ASP.NET Core не має (ASP.NET "Спадщина").

Код загального призначення все одно повинен використовувати його, оскільки він може працювати з SynchronizationContext.

ASP.NET Core SynchronizationContext


17
Просто хочу трохи пояснити, 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 Blog рекомендують використовувати 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) .
Аліссон,

1
Відповідно до цього, я б сказав, що для більшості випадків це не потрібно. Якщо ви не використовуєте власний контекст синхронізації або не використовуєте бібліотеку, яка це робить.
Аліссон,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.