在Web Api方法中调用异步方法

时间:2015-04-18 12:13:18

标签: c# asp.net-web-api async-await

我有两种方法,一种是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永远不会被发送。因此,对服务器的请求将会挂起。

1 个答案:

答案 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的方法阻止了(这反过来又等待继续完成等等......)。