Async и Await в ApiController Post
Я все еще не совсем понимаю об асинхронном режиме и жду в .net 4.5. До сих пор, я думаю, я понимаю, что ждут:
- помещает функцию (справа) в отдельный поток.
- возвращает выполнение текущему вызову функции
- но удерживает остальную часть текущего кода функции "заложник" до тех пор, пока ожидающая (асинхронная) функция не будет завершена.
Пожалуйста, поправьте меня, если я что-то не понимаю. Итак, если это верно, я застрял с функцией ApiController Post, которую я хочу асинхронно:
[HttpPost]
public async Task<HttpResponseMessage> Post([FromBody]MyObject obj)
{
myDataContext.MyObjects.InsertOnSubmit(obj);
myDataContext.SubmitChanges();
await SomeReallyLongRunningTaskAsync();
// obj would now have the new Id, which I'm really after.
return Request.CreateResponse(HttpStatusCode.Created, obj);
}
Итак, если я правильно понимаю это, Post завершит выполнение и вернет управление тем, кто вызвал myApiController.Post(obj)
. Но у меня нет объекта HttpResponseMessage
еще с тех пор, как вы ожидаете return Request.CreateResponse(HttpStatusCode.Created, obj);
"заложника".
В этом вышеприведенном простом примере вызов немедленно вернется к клиенту (то есть к клиентскому JS-сайту или мобильному приложению)? Если да, то это будет 201, 400, 500 (лучше не), другие?
Ответы
Ответ 1
В дополнение к ответу Стивена мне нужно указать несколько вещей.
Во-первых, асинхронизация в контроллере не делает работу пользователя асинхронной. Пользователь должен будет ждать, пока будет SomeReallyLongRunningTaskAsync()
. [Итак, почему мы делаем async? См. Следующий пункт]
Кроме того, если SomeReallyLongRunningTaskAsync()
привязан к процессору, вы не должны вызывать его в режиме async. Основная причина для использования Async в сценарии сервера - освободить поток CLR обратно в пул, чтобы IOP может справиться с остальными - до тех пор, пока IO не будет выполнена, а затем вернется в пул потоков. Это предотвратит проблему Thread Starvation, которая распространена в сценариях ASP.NET.
IOCP используются ТОЛЬКО в ситуациях IO-bound, примеры:
- чтение/запись в файл
- доступ к базе данных или
- доступ к внешней веб-службе или службе WCF
В Интернете доступно множество ресурсов и объясняются различные аспекты. Если я могу поместить пробку, глава 2 этой книги - отличный ресурс, который дает цельное понимание Async в веб-API.
Ответ 2
помещает функцию (справа) в отдельный поток.
Нет. async
не запускает новый поток. У меня есть async
intro, которое может оказаться полезным.
Сообщение завершает выполнение и возвращает управление тому, кто вызвал myApiController.Post(obj). Но у меня еще нет объекта HttpResponseMessage.
Правильно.
В этом вышеприведенном простом примере вызов немедленно вернется к клиенту (то есть клиентскому веб-сайту JS или мобильному приложению)?
Нет. ASP.NET MVC 4.5 видит, что вы возвращаете Task<HttpResponseMessage>
, а не HttpResponseMessage
, поэтому он не будет отправлять ответ до завершения Task
(в конце вашего метода async
Post
).