Оновлення: ASP.NET Core не маєSynchronizationContext
. Якщо ви перебуваєте на ASP.NET Core, не має значення, використовуєте ви його ConfigureAwait(false)
чи ні.
Для ASP.NET "Повний" або "Класичний" або що завгодно, решта цієї відповіді все ще стосується.
Оригінальна публікація (для непрофільних ASP.NET):
Це відео команди ASP.NET має найкращу інформацію про використання async
на ASP.NET.
Я читав, що він є більш ефективним, оскільки йому не потрібно перемикати контексти потоків назад до початкового контексту потоку.
Це вірно з програмами інтерфейсу, де є лише одна нитка інтерфейсу, до якої ви повинні "синхронізувати" назад.
В ASP.NET ситуація дещо складніша. Коли async
метод відновить виконання, він захоплює нитку з пулу потоків ASP.NET. Якщо ви вимкнете захоплення контексту за допомогою ConfigureAwait(false)
, то потік просто продовжує виконувати метод безпосередньо. Якщо ви не відключите захоплення контексту, то потік знову введе контекст запиту, а потім продовжить виконання методу.
Тому ConfigureAwait(false)
не врятує вас стрибок потоку в ASP.NET; це врятує вас від повторного введення в контекст запиту, але це, як правило, дуже швидко. ConfigureAwait(false)
може бути корисним, якщо ви намагаєтеся виконати невелику кількість паралельної обробки запиту, але насправді TPL найкраще підходить для більшості таких сценаріїв.
Однак із ASP.NET Web Api, якщо ваш запит надходить на один потік, і ви очікуєте певної функції і зателефонуєте ConfigureAwait (false), який потенційно може перевести вас на інший потік, коли ви повертаєте кінцевий результат функції ApiController .
Власне, просто робити це await
може зробити це. Як тільки ваш async
метод потрапляє на await
, метод блокується, але потік повертається до пулу потоків. Коли метод готовий до продовження, будь-яка нитка відривається з пулу потоків і використовується для відновлення методу.
Єдина відмінність ConfigureAwait
у ASP.NET полягає в тому, чи входить цей потік у контекст запиту під час відновлення методу.
Я маю більше довідкової інформації у своїй статті MSDNSynchronizationContext
та в своєму async
вступному дописі в блозі .
HttpContext.Current
передається через ASP.NETSynchronizationContext
, який за замовчуванням передається, коли виawait
, але це не передаєтьсяContinueWith
. OTOH, контекст виконання (включаючи обмеження безпеки) - це контекст, згаданий у CLR через C #, і він передається обомаContinueWith
таawait
(навіть якщо ви використовуєтеConfigureAwait(false)
).