В этом API есть некоторый код, который выполняется долгое время, поэтому я хочу сделать этот асинхронный.
Этот ответ рекомендует "асинхронный шаблон".В частности, это шаблон асинхронного обмена сообщениями .Этот шаблон не имеет ничего общего с ключевыми словами async
и await
.В шаблоне асинхронного обмена сообщениями используется термин «асинхронный» с очень широким определением;Ключевое слово async
- это одна очень специфическая реализация асинхронности, которая здесь не применяется.
Чтобы на самом деле решить вашу проблему, вы должны заставить свой метод действия сгенерировать идентификатор запроса, добавить сообщение «запрос» в надежныйочередь (например, очередь Azure) и верните идентификатор запроса клиенту.Далее вам понадобится независимый фоновый работник;поскольку ваше веб-приложение является службой приложений Azure, вы можете найти веб-задания Azure хорошим выбором для фоновых работников, хотя вам следует учитывать и функции Azure.Наконец, вам понадобится способ связи рабочего с вашим интерфейсом, чтобы он знал, когда работа будет завершена;Здесь существует множество возможных подходов, от SignalR до некоторой общей «рабочей базы данных», которую веб-интерфейс может опрашивать через ваш API-интерфейс службы приложений.
И, во-вторых, если он отправляет управление обратно в 'ждите ', тогда когда и как оператор return отправляет значение обратно?
Вы правы;HTTP-ответ не может быть отправлен обратно на await
, иначе невозможно будет отправить фактическое значение результата в качестве ответа.
Согласно этой документации,Ключевое слово await должно возвращать элемент управления функции вызывающей стороны (в данном случае почтальону)
Именно в этом и заключается недоразумение.Почтальон не вызвал вашу функцию;ASP.NET сделал.await
правильно уступает ASP.NET, который возвращает поток запроса в пул потоков.ASP.NET не завершает запрос, пока не завершится метод действия.