Подтвердить что ты не робот

Существует ли опасность использования ConfigureAwait (false) в контроллерах WebApi или MVC?

Скажем, у меня есть два сценария:

1) Контроллер WebApi

    [System.Web.Http.HttpPost]
    [System.Web.Http.AllowAnonymous]
    [Route("api/registerMobile")]
    public async Task<HttpResponseMessage> RegisterMobile(RegisterModel model)
    {
        var registerResponse = await AuthUtilities.RegisterUserAsync(model, _userService, User);
        if (registerResponse.Success) {
            var response = await _userService.GetAuthViewModelAsync(model.Username, User);
            return Request.CreateResponse(HttpStatusCode.OK, new ApiResponseDto() { Success = true, Data = response });
        }
        else {
            return Request.CreateResponse(HttpStatusCode.OK, registerResponse);
        }

    }

2) MVC-контроллер

    [Route("public")]
    public async Task<ActionResult> Public()
    {
        if (User.Identity.IsAuthenticated)
        {
            var model = await _userService.GetAuthViewModelAsync(User.Identity.Name);
            return View("~/Views/Home/Index.cshtml", model);
        }
        else
        {
            var model = await _userService.GetAuthViewModelAsync(null);
            return View("~/Views/Home/Index.cshtml", model);
        }
    }

Я читал, когда я должен использовать ConfigureAwait, и мне кажется, что я должен использовать ConfigureAwait(false) для ВСЕХ моих асинхронных вызовов, которые не привязаны непосредственно к пользовательскому интерфейсу. Я не знаю, что это значит, хотя... я должен использовать .ConfigureAwait(false) для всех вышеперечисленных вызовов await?

Я ищу некоторые недвусмысленные рекомендации, когда именно я должен его использовать.

Этот вопрос НЕ совпадает с Лучшей практикой для вызова ConfigureAwait для всего кода на стороне сервера - Я ищу простой ответ в прецеденте для этот метод в контексте WebApi и MVC, а не как общий С#.

4b9b3361

Ответ 1

похоже, что я должен использовать ConfigureAwait (false) для ВСЕХ моих асинхронных вызовов, которые не привязаны непосредственно к пользовательскому интерфейсу.

Не совсем. Это руководство не имеет смысла здесь, поскольку нет нити пользовательского интерфейса.

Параметр, передаваемый в ConfigureAwait, равен continueOnCapturedContext, что более четко объясняет сценарий. Вы хотите использовать ConfigureAwait(false) всякий раз, когда остальная часть этого метода async не зависит от текущего контекста.

В ASP.NET 4.x контекст представляет собой контекст запроса, который включает в себя такие вещи, как HttpContext.Current и культура. Также - и это недокументированная часть - многие вспомогательные методы ASP.NET зависят от контекста запроса.

(Боковое примечание: Ядро ASP.NET больше не имеет "контекста" )

Должен ли я использовать .ConfigureAwait(false) для всех вышеперечисленных ожидающих вызовов?

Я не слышал никаких твердых рекомендаций по этому поводу, но я подозреваю, что все в порядке.

В моем собственном коде я никогда не использую ConfigureAwait(false) в моих методах действий с контроллером, так что они уже завершаются в контексте запроса. Мне это кажется более правильным.

Ответ 2

Вы можете использовать ConfigureAwait в общедоступном действии MVC Controller, это помогает предотвратить блокировку сделки, если ваш _userService.GetAuthViewModelAsync продолжает ждать. он тупик поднимает тупик, если служба асинхронного обслуживания продолжает ждать, поэтому может заблокировать httpcontext пользовательского интерфейса.

Посмотрите ниже ссылку, чтобы понять этот случай:

http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

Ответ 3

Async/Await - лучшие практики в асинхронном программировании

async Task MyMethodAsync()
    {
      // Code here runs in the original context.
      await Task.Delay(1000);
      // Code here runs in the original context.
      await Task.Delay(1000).ConfigureAwait(
        continueOnCapturedContext: false);
      // Code here runs without the original
      // context (in this case, on the thread pool).
    }

Помимо производительности, ConfigureAwait имеет еще один важный аспект: он может избежать взаимоблокировок. Если вы добавите "ConfigureAwait (false)" в строку кода в DelayAsync, тогда тупика избегают. На этот раз, когда ожидание завершится, он попытается выполнить оставшуюся часть асинхронного метода в контексте пула потоков. Метод может завершить, что завершает возвращенную задачу, а theres нет тупика. Этот метод особенно полезен, если вам необходимо постепенно конвертировать приложение из синхронного в асинхронное.