使用异步调用时实体框架挂起

时间:2014-06-18 14:59:55

标签: c# entity-framework asynchronous asp.net-mvc-5.1

我是使用异步的新手,这似乎让我不知道原因或问题是什么,当我尝试加载网页时,异步调用似乎挂起并且页面永远不会被加载。这是我的实施错了吗?

CONTROLLER

public ActionResult Index()
{

    var model = _partyAddOnService.Get().Result.Select(x => new AddOnModel()
    {
        Id = x.Id,
        AddOnType = x.AddOnType,
        Description = x.Description,
        Name = x.Name,
        Price = x.Price
    });

    return View(model);
}

SERVICE

public async Task<IEnumerable<AddOn>> Get()
{
    return await _repository.GetAsync();
}

REPOSITORY

public async Task<IEnumerable<T>> GetAsync()
{
    return await Context.Set<T>().ToListAsync();
}

更新:

我也试过这个,它仍然挂起......

public ActionResult Index()
{

    var model = _partyAddOnService.Get();
    return View();
}

* 调试并查看“任务”状态时,显示“正在等待激活”

还尝试使用配置文件建议的ConfigureAwait方法。 (见詹姆斯评论如下)

public async Task<IEnumerable<AddOn>> Get()
{
    return await _repository.GetAsync().ConfigureAwait(false);
}

2 个答案:

答案 0 :(得分:5)

为防止死锁,请一直使用async。您已经在服务和存储库中使用它,因此只需将其添加到您的控制器:

public async Task<ActionResult> Index()
{
  var model = (await _partyAddOnService.Get()).Select(x => new AddOnModel()
  {
    Id = x.Id,
    AddOnType = x.AddOnType,
    Description = x.Description,
    Name = x.Name,
    Price = x.Price
  });

  return View(model);
}

我还建议您将异步方法更改为Async,以关注Task-based Asynchronous Pattern。即,Get应为GetAsync

答案 1 :(得分:1)

您导致死锁,因为您没有一直实现async-await模式。也可以在最低级别使用.ConfigureAwait(false)。

public async Task<ActionResult> Index()
{

    var model = await _partyAddOnService.Get().Result.Select(x => new AddOnModel()
    {
        Id = x.Id,
        AddOnType = x.AddOnType,
        Description = x.Description,
        Name = x.Name,
        Price = x.Price
    });

    return View(model);
}