2015-04-18 5 views
2

У меня есть два метода: один в WebApi (Post()) и один в моем репо репозитории (Save()). Внутри метода Save я вызываю метод async с ожиданием. Сам метод Save is async.Вызов метода async в методе WebApi

Что я в конце концов хочу сделать, так это то, что после завершения функции в методе сохранения отправить 201 пользователю.

Web API:

public HttpResponseMessage Post(JObject input) 
{ 
    Event postedEvent = new Event(// here be data //); 
    IEventRepo repo = new MongoDBRepo(); 

    return repo.Save(postedEvent).Result; 
} 

репо Данные:

public async Task<HttpResponseMessage> Save(Event e) 
{ 
    await _collection.InsertOneAsync(e); 

    return new HttpResponseMessage(HttpStatusCode.Created); 
} 

Что происходит сейчас в том, что Сохранить будет сделано, но HttpResponseMessage никогда не будет отправлен. Таким образом, запрос на сервер будет зависать.

+1

Используйте async во время использования, иначе вы попадаете в тупик. Прочтите это: http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html –

ответ

7

У вас в тупике, так как вы заблокировали результат Task, указанный repo.Save, а не для него.

Вы должны использовать async весь путь до вашего действия контроллера:

public async Task<HttpResponseMessage> Post(JObject input) 
{ 
    Event postedEvent = new Event(/* here be data */); 
    IEventRepo repo = new MongoDBRepo(); 

    return await repo.Save(postedEvent); 
} 

Смотрите эту прекрасную blog post для более подробного объяснения причины этого тупика, но - в сущности - это вызвано факт, что продолжение для асинхронного вызова в репо ожидает в контексте запроса, который уже заблокирован методом, который вы вызываете репо (который, в свою очередь, ожидает завершения продолжения и т. д.).

+2

Спасибо. Вот и все! Я новичок в асинхронном программировании, так что простите меня за глупые вопросы :) – andreicek

+0

Nice one. Я мог видеть, что данные не были зафиксированы, но значения удостоверений были увеличены! Цените наконечник. –

Смежные вопросы