104

В чем разница между:В чем преимущество использования async с MVC5?

public ActionResult Login(LoginViewModel model, string returnUrl) 
{ 
    if (ModelState.IsValid) 
    { 
     IdentityResult result = IdentityManager.Authentication.CheckPasswordAndSignIn(AuthenticationManager, model.UserName, model.Password, model.RememberMe); 
     if (result.Success) 
     { 
      return Redirect("~/home"); 
     } 
     else 
     { 
      AddErrors(result); 
     } 
    } 
    return View(model); 
} 

и:

[HttpPost] 
[AllowAnonymous] 
[ValidateAntiForgeryToken] 
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) 
{ 
    if (ModelState.IsValid) 
    { 
     IdentityResult result = await IdentityManager.Authentication.CheckPasswordAndSignInAsync(AuthenticationManager, model.UserName, model.Password, model.RememberMe); 
     if (result.Success) 
     { 
      return Redirect("~/home"); 
     } 
     else 
     { 
      AddErrors(result); 
     } 
    } 
    return View(model); 
} 

Я вижу, что код MVC теперь имеет асинхр но какая разница. Отличается ли производительность лучше, чем другая? Легче ли отлаживать проблемы друг с другом? Должен ли я вносить изменения в другие контроллеры для моего приложения для добавления Async?

+0

В подавляющем большинстве ситуаций нет никакой серьезной выгоды для использования async в MVC, но есть много негативов –

ответ

153

Асинхронные действия полезны только при выполнении связанных операций ввода-вывода, таких как удаленные вызовы сервера. Преимущество асинхронного вызова заключается в том, что во время операции ввода-вывода не используется рабочий поток ASP.NET. Итак, вот как работает первый пример:

  1. Когда запрос попадает в действие, ASP.NET берет поток из пула потоков и начинает его выполнять.
  2. Вызывается метод IdentityManager.Authentication.CheckPasswordAndSignIn. Это блокирующий вызов -> во время всего вызова рабочий поток подвергается опасности.

А вот как работает второй вызов:

  1. Когда запрос попадает в действие, ASP.NET принимает поток из пула потоков и начинает выполнять его.
  2. Вызывается IdentityManager.Authentication.CheckPasswordAndSignInAsync, который немедленно возвращается. Порт завершения ввода-вывода зарегистрирован, и рабочий поток ASP.NET выпущен в пул потоков.
  3. Позже, когда операция завершена, порт завершения ввода-вывода сигнализируется, другой поток вытягивается из пула потоков, чтобы завершить возврат.

Как вы можете видеть во втором случае рабочие потоки ASP.NET используются только в течение короткого периода времени. Это означает, что в пуле доступно больше потоков для обслуживания других запросов.

В заключение, используйте асинхронные действия только в том случае, если внутри вы используете настоящий асинхронный API. Если вы совершаете блокирующий вызов внутри асинхронного действия, вы полностью уничтожаете его.

+0

Как насчет синхронизации контекста. Разве это не будет таким накладным, что вы вообще не хотите использовать асинхронные действия? «Накладные расходы асинхронного метода, который фактически выполняет асинхронно, полностью зависит от того, нужно ли ему переключать потоки с помощью SynchronizationContext.Post. Если это , в служебных данных преобладает переключатель потока, который он выполняет по мере его возобновления. Это означает, что текущий SynchronizationContext имеет большое значение ». (Async in C# 5.0, 2012, Alex Davies) – annemartijn

+1

@Darin Почему так важно выпустить основной поток? Ограничены ли темы? – Omtechguy

+1

@Omtechguy да Просьбы о потоках имеют определенный предел –

1

Обычно один HTTP-запрос обрабатывается одним потоком, полностью удаляя этот поток из пула, пока не будет возвращен ответ. С помощью TPL вы не связаны этим ограничением. Любой запрос, который приходит, запускает продолжение с каждой единицей вычисления, необходимой для вычисления ответа, который может выполняться в любом потоке в пуле. С помощью этой модели вы можете обрабатывать гораздо больше параллельных запросов, чем со стандартным ASP.Net.

Если это какая-то новая задача, которая будет порождена или нет, и если ее следует ждать или нет. Всегда думайте о тех 70 мс, которые прибл. макс. время, которое должен принимать любой вызов метода. Если его дольше, то ваш пользовательский интерфейс, скорее всего, не будет чувствовать себя очень отзывчивым.

0

В веб-приложениях, которые видят большое количество одновременных запросов при запуске или имеют всплеск нагрузки (когда параллелизм увеличивается внезапно), эти асинхронные вызовы веб-сервисов повысят отзывчивость вашего приложения. Асинхронный запрос обрабатывает столько же времени, сколько и синхронный запрос. Например, если запрос вызывает вызов веб-службы, для завершения которого требуется две секунды, запрос занимает две секунды, независимо от того, выполняется ли оно синхронно или асинхронно.Однако во время асинхронного вызова поток не блокируется от ответа на другие запросы, пока он ожидает завершения первого запроса. Следовательно, асинхронные запросы предотвращают очередь запросов и рост пула потоков, когда существует много параллельных запросов, которые вызывают длительные операции.

Смежные вопросы