c# - 异步/等待调用不返回。强制同步确实

标签 c# entity-framework asynchronous async-await asp.net-web-api

我遇到了 Async/Await 的问题,我无法理解。

下面的代码在 WebAPI Controller 中:

这有效(通过 .Result 强制同步)

public async Task<HttpResponseMessage> Get(long id)
{
    var distribution = this.Service.GetById(id).Result;
    var result = distribution == null ?
            Request.CreateResponse(HttpStatusCode.NotFound) :
            Request.CreateResponse(
                    HttpStatusCode.OK, 
                    distribution.AsViewModel(identity));
    return result;
}

这不是(使用 await )

public async Task<HttpResponseMessage> Get(long id)
{
    var distribution = await this.Service.GetById(id);
    var result = distribution == null ?
            Request.CreateResponse(HttpStatusCode.NotFound) : 
            Request.CreateResponse(
                    HttpStatusCode.OK, 
                    distribution.AsViewModel(identity));
    return result;
}

以下是一些观察结果和额外信息:

  • 该服务与 EF6 上的存储库对话并取出内容 数据库的 async ( .SingleOrDefaultAsync() )。
  • angular 服务触发请求,它只是在网络选项卡中保持挂起状态。此外,如果您导航到该页面,您将一无所获。其他时候你在 await 之后没有到达线路并且没有任何反应。也不异常(exception)。
  • 如果我调试服务(使用 await 关键字)并且我单步执行 编码它有时“正常工作”,我从数据库中获取数据 一切都很好。
  • Service 和 DataContext 使用 Ninject 的 InRequestScope()
  • 注入(inject)

最奇怪的是,当我在上次 sprint 发布它时,我可以发誓它是有效的。我有什么想法可以解决这个问题吗?

编辑

这是服务:

public Task<Distribution> GetById(long id)
{
    return this._distributionRepository.GetById(id);
}

这是存储库:

public Task<Distribution> GetById(long id)
{
    return this.DataContext.Distributions.SingleAsync(d => d.Id == id);
}

最佳答案

正如我在评论中提到的,到 awaitthis.Service.GetById(id)你应该声明 GetById方法 async , 和 all the way down it should be async . 所以你的代码应该是这样的

Controller

public async Task<HttpResponseMessage> Get(long id)
{
    var distribution = await this.Service.GetByIdAsync(id);
    var result = distribution == null ?
            Request.CreateResponse(HttpStatusCode.NotFound) :
            Request.CreateResponse(
                    HttpStatusCode.OK, 
                    distribution.AsViewModel(identity));
    return result;
}

服务

public async Task<Distribution> GetByIdAsync(long id)
{
    return await this._distributionRepository.GetByIdAsync(id);
}

存储库

public async Task<Distribution> GetByIdAsync(long id)
{
    return await this.DataContext.Distributions.SingleAsync(d => d.Id == id);
}

我还建议关注 async方法约定并添加async到你的异步方法,所以你应该重命名 GetById GetByIdAsync 的方法在您的服务存储库中。

关于c# - 异步/等待调用不返回。强制同步确实,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26231300/

相关文章:

c# - DataContractJsonSerializer 生成 Ghost 字符串到 JSON 键?

c# - 使用 Lazy<T> 对性能有害吗?

sql - 如何自动将实体模型更改部署到数据库?

c# - 我如何为 json 属性返回 null 而不是 "data": []

javascript - 如何在axios响应后在React中使setState同步

java - 处理长时间运行的清理逻辑以响应 Netty ChannelInactive 事件的正确方法?

c# - DbContext 更新与 EntityState 修改

c# - .NET:向 WebClient 的 UploadStringCompletedEventHandler 提交用户定义标记的最佳方式是什么

entity-framework - 云互斥: Cloud based concurrency involving read/write to shared data (SQL data)

c# - 异步调用是需要在当前进程中多出一个线程还是使用线程池中的另一个线程?