Зачем и когда нужно ждать в асинхронных функциях? - PullRequest
0 голосов
/ 18 мая 2018

Я знаю, что подобные вопросы задавались, но я борюсь с концепциями асинхронного программирования в .net.Как веб-разработчик, я понял, что асинхронный вызов функций не приводит к блокировке пользовательского интерфейса, и вы можете делать другие вещи.Но теперь я на другой стороне, пишу сервис C # Web API для извлечения информации из базы данных и выполнения некоторых вычислений.Я сделал функции в контроллере асинхронными, добавив ключевое слово async в заголовок функции, который я наивно думал, что это конец, но затем он говорит мне, что мне нужно использовать ключевое слово await в функции.Так что я понял, как это сделать (я много читал к этому моменту), но я не понимаю, ПОЧЕМУ мне нужно это делать, а также КОГДА.Например, у меня есть веб-метод, как показано ниже, где он вызывает две другие функции, но только одна вызывается с await.Это плохо?Это будет только неблокирующая часть времени?Затем я создал другую тестовую функцию, у которой нет ключевого слова await, и она работала нормально (нижний код).

[HttpPost]
public async Task<IHttpActionResult> CalculateBMIAsync([FromBody]MeasureInput patientData)
       {            
           string results = String.Empty;
           MeasureReturn returnVal = null;

           try
           {    
               string msgInvalid = await Translators.validatePatMonthXML(patientData);

               if (String.IsNullOrEmpty(msgInvalid))
               {
                   results = await measureProcessor.CalculateBMI(patientData);

               }
               else
                   return new BadRequestWithInfoResult(Translators.CreateErrorXML(new Exception(msgInvalid)));
           }
           catch (Exception ex)
           {
               return new BadRequestWithInfoResult(Translators.CreateErrorXML(ex));
           }

           return Ok<MeasureReturn>(returnVal);
       }

Пример метода веб-API, который работал асинхронно при вызове с помощью jquery (здесь не используется await):

[HttpPost]
public async Task<IHttpActionResult> CalculateTest()
{           

    long d = 0;
    for (long i = 0; i < 2000000000; i++)
    {
        d = i;
    }

    string returnVal = d.ToString();

    return Ok(returnVal);
}

Телефонный код:

 $('#btn1').click(function () {
            console.log('Ajax request');
            $.ajax({
                url: 'http://localhost:53312/api/Measures/CalculateTest',
                type: 'POST',
                success: function (data) {
                    $('#result1').html('async request finished');
                }
            })
        });

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

В контексте конечной точки веб-приложения (конечная точка API, действие контроллера и т. Д.) Не обязательно думать об этом как о «не блокировании пользовательского интерфейса».Вместо этого думайте об этом как о «не связывая нить веб-сервера».Рассмотрим веб-сервис, который выполняет некоторые операции ввода-вывода с дисками или другими системами.Сделав эти операции ввода / вывода асинхронными, веб-сервер может принимать / обрабатывать больше запросов, пока эти операции ввода / вывода вызываются.

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

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

* Примечание. Часто люди наивно не ожидают асинхронной операции, потому что они хотят, чтобы она была «запущена и забыта».Просто запомни часть «забудь».«Забудьте» означает «Мне все равно, будет ли эта операция успешной или нет».

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

0 голосов
/ 18 мая 2018

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

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

...