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

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 (лучше не), другие?

4b9b3361

Ответ 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).