我有两种方法,一种是WebApi(Post()),一种是我的数据仓库(Save())。在Save方法中,我用await调用异步方法。 Save方法本身是异步的。
我最终想要完成的是在Save方法中的功能完成后向用户发送201。
网址:
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);
}
现在发生的是Save将完成,但HttpResponseMessage永远不会被发送。因此,对服务器的请求将会挂起。
答案 0 :(得分: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,但实质上 - 它是由repo中异步调用的延续等待请求上下文的事实引起的已经被您调用repo的方法阻止了(这反过来又等待继续完成等等......)。